Dubbo的SPI机制
Java SPI
Java SPI(Service Provider Interface)
是JDK内置的一种动态加载扩展点的实现,在ClassPath的META-INF/services目录下放置一个与接口同名的文本文件,文件的内容为接口的实现类,多个实现类用换行符分隔。JDK中使用java.util.ServiceLoader来加载具体的实现。
JAVA SPI不足
1. 不需要遍历所有的实现,并且实例化,需要在循环中找到我们需要的实现
2. 配置中只是列出了扩展实现,没有命名,很难准确引用
3. 扩展如果依赖其他的扩展,做不到自动注入和装配
4. 不提供类似于spring IOC
和AOP
的功能
5. 扩展很难和其他框架集成
Dubbo的SPI机制
dubbo对原生的SPI机制进行了一些扩展。
- 扩展点
是一个java接口
- 扩展(
Extension
)
扩展点的实现类
- 扩展实例(
Extension Instance
)
扩展点实现类的实例
- 扩展自适应实例(
Extension Adaptive Instance
)
扩展的自适应实例其实就是一个Extension的代理,它实现了扩展点接口。在调用扩展点的接口方法时,会根据实际的参数来决定要使用哪个扩展。
- @SPI
@SPI注解作用于扩展点的接口上,表明该接口是一个扩展点。
- @Adaptive
@Adaptive注解用在扩展接口的方法上。表示该方法是一个自适应方法。Dubbo在为扩展点生成自适应实例时,如果方法有@Adaptive注解,会为该方法生成对应的代码。方法内部会根据方法的参数,来决定使用哪个扩展。 @Adaptive注解用在类上代表实现一个装饰类,类似于设计模式中的装饰模式,它主要作用是返回指定类,目前在整个系统中AdaptiveCompiler、AdaptiveExtensionFactory这两个类拥有该注解。
- ExtentionLoader
类似于Java SPI的ServiceLoader,负责扩展的加载和生命周期维护。
- 扩展别名
和Java SPI不同,Dubbo中的扩展都有一个别名,用于在应用中引用它们
- 一些路径
和Java SPI从/META-INF/services目录加载扩展配置类似,Dubbo也会从以下路径去加载扩展配置文件
<div>/META-INF/dubbo/internal</div>
<div>/META-INF/dubbo</div>
<div>/META-INF/services</div>
<div>```