SPI 机制
SPI(Service Provider Interface),是JDK内置的一种 服务提供发现机制,可以用来启用框架扩展和替换组件,主要是被框架的开发人员使用,比如java.sql.Driver接口,其他不同厂商可以针对同一接口做出不同的实现,MySQL和PostgreSQL都有不同的实现提供给用户,而Java的SPI机制可以为某个接口寻找服务实现。Java中SPI机制主要思想是将装配的控制权移到程序之外,在模块化设计中这个机制尤其重要,其核心思想就是 解耦。
SPI 整体机制如下:
当服务的提供者提供了一种接口的实现之后,需要在classpath下的
META-INF/services/
目录里创建一个以服务接口命名的文件,这个文件里的内容就是这个接口的具体的实现类。当其他的程序需要这个服务的时候,就可以通过查找这个jar包(一般都是以jar包做依赖)的META-INF/services/
中的配置文件,配置文件中有接口的具体实现类名,可以根据这个类名进行加载实例化,就可以使用该服务了。JDK中查找服务的实现的工具类是:java.util.ServiceLoader
示例:
1、 定义接口
public interface Search { public List<String> searchDoc(String keyWord); }
2、文件搜索实现
public class FileSearch implements Search { @Override public List<String> searchDoc(String keyWord) { System.out.println("文件搜索 " + keyWord); return null; } }
3、 数据库搜索实现
public class DatabaseSearch implements Search { @Override public List<String> searchDoc(String keyWord) { System.out.println("数据库搜索 " + keyWord); return null; } }
4、在 resources 下新建 META-INF/services/ 目录, 然后新建接口全限定名的文件: com.yyds.spi.service.Search, 里面加上我们的实现类
com.yyds.spi.service.impl.FileSearch
com.yyds.spi.service.impl.DatabaseSearch
5、 测试方法
@Test public void test() { ServiceLoader<Search> s = ServiceLoader.load(Search.class); Iterator<Search> iterator = s.iterator(); while(iterator.hasNext()) { Search search = iterator.next(); search.searchDoc("Hello World"); } }
6、输出结果