Dubbo 的 SPI 机制(三)(Extension 扩展点补充)

版权声明: https://blog.csdn.net/Dongguabai/article/details/84521361

相关博客:

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

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

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

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

createAdaptiveExtension() 方法:

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

先以 AdaptiveCompiler 为例:

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

@Adaptive注解:

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

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

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

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

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

那这个 objectFactory 到底是什么呢:

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

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

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

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

接下来再看这段代码:

这个方法有多个实现:

看看 AdaptiveExtensionFactory 的实现:

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

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

后面的就很简单了:

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

再回到 injectExtension() 方法:

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

总体流程如下:

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

猜你喜欢

转载自blog.csdn.net/Dongguabai/article/details/84521361