相关博客:

​​Dubbo的SPI机制(一)(Java的SPI)​​

​​Dubbo的SPI机制(二)(Dubbo优化后的SPI实现)​​

 

Dubbo 的 Extension 主要是基于 SPI 思想实现的自己的 SPI 的工具。

 在上一篇博客(​​Dubbo的SPI机制(二)(Dubbo优化后的SPI实现)​​)中介绍过了,在 getAdaptiveExtension() 方法中,如果instance为null,则调用 createAdaptiveExtension() 方法:

Dubbo 的 SPI 机制(三)(Extension 扩展点补充)_自适应

createAdaptiveExtension() 方法:

Dubbo 的 SPI 机制(三)(Extension 扩展点补充)_自适应_02

之前介绍过了 getAdaptiveExtensionClass() 方法,现在来看看 injectExtension() 方法。从字面意思来看,这是一个注入方法(很熟悉有木有)。

先以 AdaptiveCompiler 为例:

Dubbo 的 SPI 机制(三)(Extension 扩展点补充)_动态创建_03

有个 set 方法,本身这是一个自适应扩展点。

@Adaptive注解:

  • @Adaptive如果是加在类上, 表示当前类是一个自定义的自适应扩展点
  • 如果是加在方法级别上,表示需要动态创建一个自适应扩展点,也就是Protocol$Adaptive

 可以看出 AdaptiveCompiler 是一个自定义的扩展点,再回过头来看 createAdaptiveExtension() 方法:

Dubbo 的 SPI 机制(三)(Extension 扩展点补充)_初始化_04

 AdaptiveCompiler 是在类上使用了 @Adaptive 注解:

private Class<?> getAdaptiveExtensionClass() {
getExtensionClasses();
if (cachedAdaptiveClass != null) {
//这里会直接返回AdaptiveCompiler,不需要再动态创建了
return cachedAdaptiveClass;
}
return cachedAdaptiveClass = createAdaptiveExtensionClass();
}

再回过头看 injectExtension() 方法,通过 set 方法动态设置扩展点,类似于 Spring 的 set 注入:

Dubbo 的 SPI 机制(三)(Extension 扩展点补充)_初始化_05

那这个 objectFactory 到底是什么呢:

Dubbo 的 SPI 机制(三)(Extension 扩展点补充)_初始化_06

肯定会有一个地方要对它进行初始化:

private ExtensionLoader(Class<?> type) {
this.type = type;
objectFactory = (type == ExtensionFactory.class ? null : ExtensionLoader.getExtensionLoader(ExtensionFactory.class).getAdaptiveExtension());
}

也就是在构造 ExtensionLoader 的时候进行了初始化,这段代码就很熟悉了,之前看到过:

Dubbo 的 SPI 机制(三)(Extension 扩展点补充)_动态创建_07

如果在内存中这个扩展点还没有,就创建一个。

接下来再看这段代码:

Dubbo 的 SPI 机制(三)(Extension 扩展点补充)_动态创建_08

这个方法有多个实现:

Dubbo 的 SPI 机制(三)(Extension 扩展点补充)_自适应_09

看看 AdaptiveExtensionFactory 的实现:

Dubbo 的 SPI 机制(三)(Extension 扩展点补充)_初始化_10

这里循环了一个factories,那这个factories是哪来的呢,就是通过构造初始化的:

Dubbo 的 SPI 机制(三)(Extension 扩展点补充)_自适应_11

直接从基于 Dubbo SPI 规范中获取所有的 ExtensionFactory 的所有扩展点:

Dubbo 的 SPI 机制(三)(Extension 扩展点补充)_初始化_12

后面的就很简单了:

Dubbo 的 SPI 机制(三)(Extension 扩展点补充)_动态创建_13

循环遍历后根据参数返回扩展点。

再回到 injectExtension() 方法:

Dubbo 的 SPI 机制(三)(Extension 扩展点补充)_初始化_14

将扩展点使用 se 方法注入后,返回即可。

总体流程如下:

Dubbo 的 SPI 机制(三)(Extension 扩展点补充)_动态创建_15

最终形成一个动态的插件化的扩展。