SPI机制
简述
全程Service Provide Interface,是Java中提供的一种服务发现机制
- 它允许应用程序动态地加载和使用第三方提供的服务实现
- 而无需在代码中显示引用这些实现类
Java SPI是基于接口编程思想的具体体现,通过服务接口和其实现分离,从而具备更好的可扩展性和可维护性
如何定义一个SPI
定义一个接口
1
2
3
4package com.wereash.spi;
public interface SayService(){
void say();
}提供一个或多个实现了该接口的实现类,作为服务提供者
1
2
3
4
5
6
7
8package com.wereash.spi;
public class SayChinese implements SayService{
public void say(){
System.out.println("你好");
}
}配置文件。在src/main/resource下新建META-INF/services目录,同时新增一个以接口的权限定名:com.wereash.spi.SayService命名的文件,内容是要应用的实现类的全限定名,注意,每个实现类的全限定名占据一行
1
2com.wereash.spi.SayChinese;
com.wereash.spi.SayEnglish;使用ServiceLoader来加载该接口下提供的服务者
1
2
3
4
5
6public static void main(String[] args)throws IOException,InterruptedException{
ServiceLoader<SayService> loaders=ServiceLoader.load(SayService.class);
for(SayService sayService:loaders){
sayService.say();
}
}
实现原理
- 调用ServiceLoader.load()方法会先创建一个新的ServiceLoader,并实例化类中的成员变量
- 调用iterator()方法获取一个迭代器对象:
- ServiceLoader会判断providers对象是否有缓存实例对象,如果存在则直接返回
- 如果不存在,则执行类的加载操作:
- 读取META-INF/services/+指定接口的全限定名下的配置文件,获取所有能被实例化的类的全类限定名
- 通过反射加载并实例化类对象放在provides缓存中
- 返回该实例对象
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 WereAsh!
评论
ValineDisqus




