什么是SPI
SPI:服务提供者接口(Service Provider Interface)
官方定义:直译过来是服务提供者接口,学名为服务发现机制,它通过在classpath路径下的META-INF/services目录中查找文件,并自动加载文件里所定义的类
引入
JAVA中连接数据库
说明:
- 在JAVA中连接数据库,JAVA本身只提供了规范,涉及到的类:Driver、Connection、Statement、PrepareStatement、CallStatement,在加载驱动环节,需要具体的厂商去实现
- 具体的厂商会在自己的jar包中的classpath路径下的META-INF/services目录中存放以java接口类(java.sql.Driver)为名称的文件,内容则是厂商自己实现了的实现类的全类名,如mysql驱动(com.mysql.jdbc.Driver)
- java.util.ServiceLoader则是对此文件的加载,并实例化文件中的实现类
实现三元素:
- Service:java定义的接口规范
- ServiceProvider:各厂商的实现类
- ServiceLoader:加载类
实现思路代码如下:
public class ServiceLoader {
// 加载实现类
public void loadServiceImpl() {
// 加载
List<String> classNameList = IOUtil.spiLoad(Driver.class);
List<Driver> providers = new LinkedList<>();
for(String className : classNameList) {
Class<?> c = Class.forName(className);
// 通过反射创建对象
providers.add(c.netInstace());
}
}
}
Java的ServiceLoader
有哪些SPI
1. JDK的SPI
2. DUBBO的SPI
3. SpringBoot的SPI(spring.factories文件)
4. Slf4J
5. commoms-logging
举例说明
springboot的自动装配原理
我们在使用springboot时,springboot默认会将标注了@springapplication注解所在包及其子包下的标有一系列的诸如@controller、@service、@component的类实例化并放到ioc容器中来。
但是我们使用到的第三方框架的包名是和我们的项目目录是不一样的,所以不能使用以上方法进行实例化。
这时候,spring参考了jdk的设计思想,在META-INF下面定义了spring.factories文件,进行接口实例化的操作
总结
- SPI机制能够使接口与具体的实现类解耦,可以根据实际的业务情况启用或替换具体组件。
- SPI机制为很多框架的扩展提供了可能。
- SPI机制更多的是一种思想。