一. SPI机制
SPI ,全称为 Service Provider Interface
,是一种服务发现机制。它通过在 ClassPath 路径下的 META-INF/services 文件夹查找文件(服务接口),自动加载文件里所定义的类(服务接口的具体实现类)。
当外部程序装配这个模块的时候,就能通过该 jar 包 META-INF/services/ 里的配置文件找到具体的实现类名,并装载实例化,完成模块的注入。这样就能很好的找到服务接口的实现类,而不需要再代码里制定。
JDK 提供服务实现查找的一个工具类:java.util.ServiceLoader
二. 具体步骤
2.1.定义一个接口
2.2.编写接口的实现类
2.3.在resources/META-INF/services目录下创建该接口的全限定类名,命名的文件
2.4.在命名的文件上添加某些该接口的实现类的全限定类名
2.5.通过java.util.ServiceLoader来加载实现该接口的实现类
三. 代码示例
package com.xiaoxiaowang.springbootDemo.spi;
public interface XiaoXiaoSPIService {
/**
* say
*/
public void say();
}
package com.xiaoxiaowang.springbootDemo.spi.impl;
import com.xiaoxiaowang.springbootDemo.spi.XiaoXiaoSPIService;
/**
* @author: xxw
* @create: 2022-10
*/
public class XiaoXiaoSPIServiceImpl implements XiaoXiaoSPIService {
@Override
public void say() {
System.out.println("this is XiaoXiaoSPIServiceImpl");
}
}
package com.xiaoxiaowang.springbootDemo.spi.test;
import com.xiaoxiaowang.springbootDemo.spi.XiaoXiaoSPIService;
import java.sql.Driver;
import java.util.Iterator;
import java.util.ServiceLoader;
/**
* @author: xxw
* @create: 2022-10
*/
public class SPIMyTest {
public static void main(String[] args) {
// ServiceLoader<Driver> loadedDrivers = ServiceLoader.load(Driver.class);
// Iterator<Driver> driversIterator = loadedDrivers.iterator();
// try {
// while (driversIterator.hasNext()) {
// driversIterator.next();
// }
// } catch (Throwable t) {
// // Do nothing
// }
ServiceLoader<XiaoXiaoSPIService> loadedServices = ServiceLoader.load(XiaoXiaoSPIService.class);
Iterator<XiaoXiaoSPIService> iterator = loadedServices.iterator();
while (iterator.hasNext()){
XiaoXiaoSPIService service = iterator.next();
if (service != null){
service.say();
System.out.println("service =======> " + service.getClass().getName());
}
}
}
}
四. 测试效果
五.部分源码分析
ServiceLocator里去加载固定文件夹路径下的实现类
问题:JDBC中SPI机制的体现?
DriverManager类中通过静态代码块,java的spi机制,会去加载classpath下驱动包里的resources/META-INF/services文件下的驱动实现类
以mysql5.1.47版本jar包为例:
pom文件中添加mysql驱动依赖
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.47</version>
</dependency>
六.参考文档
Java的SPI机制学习笔记 - 墨天轮SPI学习笔记https://cdn.modb.pro/db/465099
https://blog.csdn.net/sco5282/article/details/119895312?spm=1001.2014.3001.5501