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/接口全限定名,内容为:配置名=扩展实现类全限定名,多个实现类用换行符分隔。




二、扩展点源码解析

 

  • 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,存入本地缓存。


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


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


代码2 getAdaptiveExtension():


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



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

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值