Dubbo之扩展点ExtensionLoader

阅读更多
一、扩展点简介
    Dubbo 的扩展点加载从 JDK 标准的 SPI (Service Provider Interface) 扩展点发现机制加强而来。   
    Dubbo 改进了 JDK 标准的 SPI 的以下问题:
  • JDK 标准的 SPI 会一次性实例化扩展点所有实现,如果有扩展实现初始化很耗时,但如果没用上也加载,会很浪费资源。
  • 如果扩展点加载失败,连扩展点的名称都拿不到了。比如:JDK 标准的 ScriptEngine,通过 getName() 获取脚本类型的名称,但如果 RubyScriptEngine 因为所依赖的 jruby.jar 不存在,导致 RubyScriptEngine 类加载失败,这个失败原因被吃掉了,和 ruby 对应不起来,当用户执行 ruby 脚本时,会报不支持 ruby,而不是真正失败的原因。
  • 增加了对扩展点 IoC 和 AOP 的支持,一个扩展点可以直接 setter 注入其它扩展点。

    约定:
        在扩展类的 jar 包内 1,放置扩展点配置文件 META-INF/dubbo/接口全限定名或者META-INF/dubbo/internal/接口全限定名或者META-INF/services/接口全限定名,内容为:配置名=扩展实现类全限定名,多个实现类用换行符分隔。
Dubbo之扩展点ExtensionLoader_第1张图片


二、扩展点源码解析

Dubbo之扩展点ExtensionLoader_第2张图片

  • SPI :Annotation,扩展点接口的标识,value指定缺省扩展点名。
  • Adaptive:Annotation,在ExtensionLoader生成Extension的Adaptive Instance时,为ExtensionLoader提供信息。value:在URL上找key的Value作为要Adapt成的Extension名。
  • Activate:Annotation,对于可以被框架中自动激活加载扩展,此Annotation用于配置扩展被自动激活加载条件。比如,过滤扩展,有多个实现,使用Activate Annotation的扩展可以根据条件被自动加载。
  • ExtensionFactory:interface,是一个扩展点,有@SPI注解,有三个实现:SpringExtensionFactory,AdaptiveExtensionFactory,SpiExtensionFactory
  • AdaptiveExtensionFactory:是ExtensionFactory的扩展点Adaptive Instance。有@Adaptive注解。
  • SpiExtensionFactory:会从ExtensionLoader中获取扩展点。
  • SpringExtensionFactory:会从spring的ApplicationContext中获取扩展点。
  • ExtensionLoader:扩展点加载器,Dubbo使用它获取扩展点。


跟代码

private static final Protocol refprotocol = ExtensionLoader.getExtensionLoader(Protocol.class).getExtension("registry");
private static final Protocol refprotocol2 = ExtensionLoader.getExtensionLoader(Protocol.class).getAdaptiveExtension();

    代码1 getExtension:
    1. getExtensionLoader()会new 一个ExtensionLoader,存入本地缓存。
Dubbo之扩展点ExtensionLoader_第3张图片

    2. getExtension()会调用createExtension(),getExtensionClasses()会加载META-INF/dubbo/接口全限定名,META-INF/dubbo/internal/接口全限定名,META-INF/services/接口全限定名的扩展点配置,如果有wrapperClasses,wrapperClasses包装原instance,生成一个新的instance。
Dubbo之扩展点ExtensionLoader_第4张图片

    3. cachedWrapperClasses是在loadFile()加载扩展点配置时,如果扩展点实现类有clazz.getConstructor(type)带类型的构造方法。以com.alibaba.dubbo.rpc.Protocol为例,ProtocolFilterWrapper,ProtocolListenerWrapper,QosProtocolWrapper就会包装原Protocol实例。
Dubbo之扩展点ExtensionLoader_第5张图片
Dubbo之扩展点ExtensionLoader_第6张图片


    代码2 getAdaptiveExtension():

    1. getAdaptiveExtension()就是返回有@Adaptive注解的实现类,在loadFile()加载扩展点配置时,会扫描@Adaptive注解。
Dubbo之扩展点ExtensionLoader_第7张图片

    2. 如果所有实现类都没有@Adaptive注解,就会调用createAdaptiveExtensionClass()动态生成一个扩展点的实现类。以com.alibaba.dubbo.rpc.Protocol为例,会生成一个名为“Protocol$Adaptive”的动态类。@SPI的value指定了默认扩展点名,@Adaptive的value指定了扩展点名从URL中的哪个属性的值,如果@Adaptive的value未指定则默认取接口名protocol。最终调用指定的扩展点名的扩展点实现类。

Dubbo之扩展点ExtensionLoader_第8张图片
Dubbo之扩展点ExtensionLoader_第9张图片
  • Dubbo之扩展点ExtensionLoader_第10张图片
  • 大小: 42.6 KB
  • Dubbo之扩展点ExtensionLoader_第11张图片
  • 大小: 175.5 KB
  • Dubbo之扩展点ExtensionLoader_第12张图片
  • 大小: 112.1 KB
  • Dubbo之扩展点ExtensionLoader_第13张图片
  • 大小: 100.1 KB
  • Dubbo之扩展点ExtensionLoader_第14张图片
  • 大小: 93.4 KB
  • Dubbo之扩展点ExtensionLoader_第15张图片
  • 大小: 95.6 KB
  • Dubbo之扩展点ExtensionLoader_第16张图片
  • 大小: 93.3 KB
  • Dubbo之扩展点ExtensionLoader_第17张图片
  • 大小: 136.8 KB
  • Dubbo之扩展点ExtensionLoader_第18张图片
  • 大小: 154.6 KB
  • 查看图片附件

你可能感兴趣的:(ExtensionLoader,扩展点,dubbo,SPI,Adaptive)