配合 JavaPoet 食用更佳
SPI 全称为 (Service Provider Interface) ,是JDK内置的一种服务提供发现机制。
当服务的提供者,提供了服务接口的一种实现之后,在jar包的META-INF/services/
目录里同时创建一个以服务接口命名的文件。该文件里就是实现该服务接口的具体实现类。而当外部程序装配这个模块的时候,就能通过该jar包META-INF/services/
里的配置文件找到具体的实现类名,并装载实例化,完成模块的注入。 基于这样一个约定就能很好的找到服务接口的实现类,而不需要再代码里制定。
JDK提供服务实现查找的一个工具类:java.util.ServiceLoader
。
举个栗子🌰
定义一个接口
public interface IProvider {
String getName();
}
定义实现类
public class ProviderA implements IProvider {
@Override
public String getName() {
return "I'm ProviderA";
}
}
public class ProviderB implements IProvider {
@Override
public String getName() {
return "I'm ProviderB";
}
}
在src/main
目录下创建resources/META-INF/services
文件夹,在services
下创建文件名是接口完整路径的文件pers.victor.test.IProvider
,文件内写入实现类的完整路径,如果有多个实现类则一行写一个,文件内容如下
pers.victor.test.ProviderA
pers.victor.test.ProviderB
在代码里获取实现类实例
ServiceLoader<IProvider> serviceLoader = ServiceLoader.load(IProvider.class);
for (IProvider provider : serviceLoader) {
System.out.println(provider.getName());
}
打印结果
I'm ProviderA
I'm ProviderB
成功地利用接口获取了实现类。
如果工程内有AB模块不互相依赖但是想做一些调用之类的,SPI可以提供一种思路。
因为文件夹和文件的创建都是手动完成的,比较繁琐,这个时候可以和JavaPoet
配合使用,在编译时创建文件夹和文件,省时省力。