概述
SPI全称Service Provider Interface,是一种为框架提供良好扩展性的机制。一般由框架开发方定义接口规范(如java.sql.Driver),而第三方厂商为之提供自己的实现(如com.mysql.jdbc.Driver)。借助SPI机制可以达到不修改框架具体实现代码就能根据依赖自动切换具体实现方案(实现类)的效果。
使用
Java SPI使用了策略模式,一个接口多种实现,这一点从概述中我们已经能够体会的到。
框架接口定义
定义一个接口及对应的方法
public interface PrintService{
void printInfo();
}
第三方厂商提供实现
编写该接口的一个实现类,各厂商提供各自的实现
public class PrintServiceImpl implements PrintService{
@Override
public void printInfo(){
System.out.println("hello world");
}
}
第三方厂商创建配置文件
各第三方实现包(项目)需要在resources/META-INF/services目录下,创建一个以接口全路径命名的文件,如com.test.spi.PrintService。用于框架寻找实现类位置。
内容为具体实现类的全路径名,如果有多个,则用分隔符分割。
com.third.spi.PrintServiceImpl
框架中调用SPI的具体实现
SPI的具体实现的调用通过java.util.ServiceLoader来加载具体的实现类。
public static void main(String[] args{
ServiceLoader<PrintService>printLoader=ServiceLoader.load(PrintService.class);
for (PrintService pintService : printerLoader) {
pintService.printInfo();
}
}
总结
通过以上使用,我们可以看出,只有更改不同的第三方厂商提供的依赖包,从而我们的框架会通过ServiceLoader调用同的实现类,从而达到了只修改依赖就变更了具体实现方案的良好扩展效果。
参考资料
《深入理解Apache Dubbo与实战》