Java中的SPI机制
- 什么是SPI
SPI全程为Service Provider Interface,服务提供接口,是Java提供的一套用来被第三方实现或者扩展的API,它可以用来启用框架扩展和替换组件。
Java SPI本质上其实就是“基于接口编程+策略模式+配置文件”组合实现的动态加载机制。
- 什么时候用SPI
在面向对象的设计里,我们一般推荐模块之间基于接口编程,模块之间不对实现类进行硬编码。一旦代码里涉及具体的实现类,就违反了可插拔的原则,如果需要替换一种实现,就需要修改代码。为了实现在模块装配的时候不用在程序里动态指明,这就需要一种服务发现机制。Java spi就是提供这样的一个机制:为某个接口寻找服务实现的机制。
很多开源框架中都采用了SPI思想,比如jdbc(Java 规定了JDBC的接口,可由不同厂商来实现MySQL,Oracle等),开源工具箱Geotools里面的DataStoreFactorySpi,我们可以自己去实现不同的DataStoreFactory,来支持不同数据引擎。
- Java SPI的约定
当服务的提供者提供了服务接口的一种实现之久,在jar包的META-INF/Services/目录中同时创建一个以服务接口命名的文件。该文件里就是实现该服务接口的具体实现类。而当外部程序装配这个模块的时候,就能通过该jar包META-INF/Services/的配置文件找到具体的实现类名。并装载实例化,完成模块的注入。基于这样的一个约定就能很好的找到服务接口的实现类,而不需要在代码里指定。
以Geotools的DataStoreFactorySpi为例,我们在org.geotools.data包里定义了接口
我们在另一包里提供了关于PostGIS的实现PostgisNGDataStoreFactory
同时在jar包的META-INF/Services/目录中同时创了建一个以服务接口命名的文件,并约定了实现类名如下:
同时提供一个查找所有实现类的工具:DataAccessFinder,客户端可以使用该工具获取到所有实现该接口的类,而不需要对类进行硬编码,这样的一个好处就是我们在jar中替换了DataStoreFactorySpi的实现类后,不会对客户端的编码产生任何影响。
- 综上
SPI就是一种将服务接口与服务实现分离以达到解耦、大大提升了程序可扩展行性的机制。引入服务提供者就是引入了SPI接口的实现者,通过本地注册来发现获取到具体的实现类。实现轻松可插拔。
- 一个应用案例
https://www.cnblogs.com/mohanchen/p/10821841.html