java对SPI的支持

目录

1. 源码的注释描述

2. 源码逻辑

3. SPI扩展的场景


1. 源码的注释描述

ServiceLoader,一种服务提供者加载工具,体现了java原生SPI扩展机制。也可以参考其逻辑实现自己的服务加载器。

服务指的是接口或抽象类,服务提供者指的是服务的实现。服务提供者以扩展的方式被加载和实例化,例如把jar包放到规定的扩展路径中、放到应用的classpath中或平台特定的方式。工具会加载并实例化提供者实现类,强制要求提供者实现类必须有无参数的构造函数。

服务提供者需要在项目的resources下创建资源路径(默认为META-INFO/services),提供者新增一个文件,文件名为服务的全路径类名,按行添加文件内容,一个服务实现类的全路径类名作为一行,使用#添加注释,且文件必须utf-8编码。

举一个例子

第一步,定义扩展点和扩展实现。如下的目录结构,MYSPIInterface作为扩展点,spiimpl下为两个扩展实现类:

第二步,添加文件配置。注意文件路径和文件名。

第三步,使用SPI获取扩展点实现类实例

ServiceLoader<MySPIInterface> load = ServiceLoader.load(MySPIInterface.class);
for (MySPIInterface mySPIInterface : load) {
	System.out.println(mySPIInterface.who());
}

明确的提供者实现类出现在多个配置文件中或同一文件中列举多次,重复列举的部分会被忽略。

服务提供者的加载和实例化都是延迟进行的。使用linkedHashMap维护已加载且实例化的提供者。iterator()方法首先遍历这个cache,然后定位并解析配置文件、加载和实例化提供者,实例放入cache。reload()方法清空cache。

非线程安全

2. 源码逻辑

ServiceLoader

LazyIterator

private class LazyIterator implements Iterator<S>

load(xxx)

public static ServiceLoader load(xxx) 返回一个serviceLoader实例

iterator()

public Iterator<S> iterator() 遍历获取提供者实例

3. SPI扩展的场景

优点

模块之间解耦,开关原则,对扩展开放,对修改关闭。

场景

  • 对某些中间件进行SPI扩展

中间件A支持SPI扩展,项目B依赖A的jar,可以在B中提供服务提供者,即实现A中允许SPI扩展的接口,按照A制定的规则编辑扩展配置。如dubbo支持协议、调用拦截扩展等

  • 自己的系统支持SPI扩展 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值