SPI 是一种接口设计模式,允许第三方(服务提供者)通过实现接口来扩展系统的功能。框架或库定义接口,第三方实现这些接口并将其实现提供给框架使用。SPI 主要用于实现可插拔的架构。
ServiceLoader
)动态加载服务提供者的实现,并在运行时使用它们。// MessageService.java
public interface MessageService {
void sendMessage(String message);
}
// EmailMessageService.java
package com.example.impl;
import com.example.MessageService;
public class EmailMessageService implements MessageService {
@Override
public void sendMessage(String message) {
System.out.println("Sending email message: " + message);
}
}
// SmsMessageService.java
package com.example.impl;
import com.example.MessageService;
public class SmsMessageService implements MessageService {
@Override
public void sendMessage(String message) {
System.out.println("Sending SMS message: " + message);
}
}
在 META-INF/services
目录下创建文件 com.example.MessageService
,内容为实现类的全限定名:
com.example.impl.EmailMessageService
com.example.impl.SmsMessageService
// MessageProcessor.java
import java.util.ServiceLoader;
public class MessageProcessor {
public static void main(String[] args) {
ServiceLoader<MessageService> loader = ServiceLoader.load(MessageService.class);
for (MessageService service : loader) {
service.sendMessage("Hello, World!");
}
}
}
API 是一组定义良好的函数或方法,用于向应用程序开发者暴露功能。API 提供一种访问系统功能的标准方式,不涉及实现细节。API 的设计目标是简洁、稳定和易用。
// CalculatorService.java
public interface CalculatorService {
int add(int a, int b);
int subtract(int a, int b);
}
// CalculatorServiceImpl.java
public class CalculatorServiceImpl implements CalculatorService {
@Override
public int add(int a, int b) {
return a + b;
}
@Override
public int subtract(int a, int b) {
return a - b;
}
}
// CalculatorClient.java
public class CalculatorClient {
public static void main(String[] args) {
CalculatorService calculator = new CalculatorServiceImpl();
System.out.println("Addition: " + calculator.add(5, 3));
System.out.println("Subtraction: " + calculator.subtract(5, 3));
}
}
java.util.List
接口,它提供了列表的操作方法(如 add
、remove
),而具体实现可以是 ArrayList
或 LinkedList
。javax.imageio.spi
包,其中 ImageReaderSpi
接口允许开发者提供自己的图片读取器实现。java.util.List
接口。SPI 和 API 都是接口设计的关键概念,但它们的使用场景和设计原则有所不同。API 主要用于提供功能和服务,强调稳定性和易用性;而 SPI 主要用于扩展和定制框架,强调灵活性和可扩展性。在实际开发中,合理使用这两种接口设计模式,可以极大地提高系统的模块化程度和可维护性。