定义

SPI 全称为 (Service Provider Interface) ,是 JDK 内置的一种服务提供发现机制。SPI 是一种动态替换发现的机制, 比如有个接口,想运行时动态的给它添加实现,你只需要添加一个实现。我们经常遇到的就是 java.sql.Driver 接口,其他不同厂商可以针对同一接口做出不同的实现,mysql 和 postgresql 都有不同的实现提供给用户,而 Java 的 SPI 机制可以为某个接口寻找服务实现。

1.jpg

类图中,接口对应定义的抽象 SPI 接口;实现方实现 SPI 接口;调用方依赖 SPI 接口。

SPI 与 API 区别

API(Application Programming Interface ),大多数情况下,都是实现方来制定接口并完成对接口的不同实现,调用方仅仅依赖却无权选择不同实现。

SPI(Service Provider Interface),而如果是调用方来制定接口,实现方来针对接口来实现不同的实现。调用方来选择自己需要的实现方。

示例

当服务的提供者提供了一种接口的实现之后,需要在 classpath 下的 META-INF/services/ 目录里创建一个以服务接口命名的文件,这个文件里的内容就是这个接口的具体的实现类。当其他的程序需要这个服务的时候,就可以通过查找这个 jar 包(一般都是以 jar 包做依赖)的 META-INF/services/ 中的配置文件,配置文件中有接口的具体实现类名,可以根据这个类名进行加载实例化,就可以使用该服务了。JDK 中查找服务实现的工具类是:java.util.ServiceLoader。

代码示例:
https://gitee.com/yin_jw/demo/tree/master/pattern-demo/src/main/java/com/yjw/demo/pattern/spi

目录结构如下图所示,接口 SqlDriver 定义了两个实现类 MysqlDriver 和 OracleDriver,META-INF 中配置接口和实现类的关系,在 SPITest 类中使用 ServiceLoader 加载 SqlDriver 的实现类。

image.png

参考

Java SPI机制详解