什么是SPI
SPI全称Service Provider Interface,是Java提供的一套用来被第三方实现或者扩展的API,它可以用来启用框架扩展和替换组件。 Java SPI 实际上是“ 基于接口的编程+策略模式+配置文件 ”组合实现的动态加载机制。 系统设计的各个抽象,往往有很多不同的实现方案,在面向的对象的设计里,一般推荐模块之间基于接口编程,模块之间不对实现类进行硬编码。
SPI与策略模式的区别【2】
从代码层面看,策略模式还是在原有项目中进行代码修改,只是不会修改原有类的代码,而是新建类;SPI机制是不会修改原有项目中代码,其会新建一个项目,最终以Jar包引入的方式代码(当然在同个项目中也是可以的)
两者目的都是解耦,但策略模式只能在类层次上做隔离,更适合在业务代码领域;而SPI机制更多则是框架的设计领域,通过SPI机制提供的灵活性,让框架拥有良好的插件特性,便于扩展
SPI与API区别
Java程序员常常是面向接口编程,SPI与面向接口编程是紧密相关的。简单地说,如果一个接口由调用方来定义而接口实现由提供方实现,这个就是SPI;如果接口的定义和实现都由提供方完成,就是我们常说的API
SPI(Service Provider Interface)服务提供接口,简单来说就是用来解耦,实现插件的自由插拔,具体实现方案可参考JDK里的ServiceLoader(加载classpath下所有META-INF/services/目录下的对应给定接口包路径的文件,然后通过反射实例化配置的所有实现类,以此将接口定义和逻辑实现分离)
Example
SPI机制是加载classpath下所有META-INF/services/目录下的对应给定接口包路径的文件。demo中加载的是per.java.basic.example.spi.Search
接口,故文件名称也是per.java.basic.example.spi.Search
,文件内容是该接口的实现类
接口类
package per.java.basic.example.spi;
import java.util.List;
public interface Search {
public List<String> doSearch(String keyword);
}
实现类1:DataBaseSearch
package per.java.basic.example.spi.impl;
import per.java.basic.example.spi.Search;
import java.util.List;
public class DataBaseSearch implements Search {
@Override
public List<String> doSearch(String keyword) {
System.out.println("implement by database");
return null;
}
}
实现类2:FileSearch
package per.java.basic.example.spi.impl;
import per.java.basic.example.spi.Search;
import java.util.List;
public class FileSearch implements Search {
@Override
public List<String> doSearch(String keyword) {
System.out.println("implement by file");
return null;
}
}
参考
【1】https://zhuanlan.zhihu.com/p/28909673
【2】https://www.cnblogs.com/chanshuyi/p/the_difference_between_spi_and_strategy.html