善忘技术夹 Logo
善忘技术夹
技术文章 · 4393 阅读

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 IOCAOP的功能 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也会从以下路径去加载扩展配置文件 ```

/META-INF/dubbo/internal

/META-INF/dubbo

/META-INF/services