其实Dubbo的扩展点加载机制网上的文章很多,有一些堪称经典,但是今天我写一下
想法,不是为了哗众取宠,只不过想梳理一下我的思路和表达我自己见解!
JDK自己提供了一种接口的实现类加载机制 SPI (service provider interface), 有兴趣的可以自行百度,
这里不展开了! 难道Dubbo的作者在重复造轮子,其实不是的,java SPI存在一些缺陷,Dubbo自己实现了扩展
加载对java SPI功能进行了增强!
1、 java SPI 缺陷1)每次加载会加载所有的实现类(不管你是否需要);
2)获取扩展类实例的粒度太粗,只能遍历(如果可以根据指定参数获取,更快捷);
3)无法对加载的扩展点类进行动态包装,功能单一;
2、Dubbo的增强扩展点加载解决了 java SPI这些缺陷,实现更加灵活的加载机制
1)Dubbo增强扩展点加载组件的配置文件的路径
类路径下的 "META-INF/services/"、"META-INF/dubbo/"、"META-INF/dubbo/internal/"
文件内容格式 key=value
2)Dubbo增强扩展点加载的逻辑结构
dubbo spi会为每一种接口类型创建一个新的ExtensionLoader实例, 然后由具体的loader负责加载和包装特定接口下的各种具体实现类,
如图,是源码图:
3) dubbo SPI采用了懒加载机制,源码如图:
方法createExtension的具体实现:
上边的装饰机制,在dubbo的很多组件中都有应用,这里以Protocol组件来简单分析,便于理解
Dubbo的Protocol实现中有两个重要的装饰类 ProtocolFilterWrapper 和 ProtocolListenerWrapper, 主要实现
对具体协议的功能增强,比如DubboProtocol,当加载DubboProtocol扩展时,加载器会自动给DubboProtocol实例
利用装饰器模式加上filter和listener功能,源码实现
instance = injectExtension((T) wrapperClass.getConstructor(type).newInstance(instance));
4)Dubbo的扩展加载类适配机制
类适配机制(准确是说是方法适配),是Dubbo各模块实现 数据模型(URL)统一基础,所以理解了它,基本就可以
在分析Dubbo的其他组件流程时,看到接口方法调用时,不会懵逼它到底执行哪一个具体实现的方法.
还是以源码为例, 加载器中的 这个方法getAdaptiveExtension() Dubbo常用获取适配扩展的方法,分析之.
看 createAdaptiveExtension()具体的实现:
接着分析getAdaptiveExtensionClass() :
对于没有添加注解类,执行createAdaptiveExtensionClass(),分析之
dubbo是如何创建适配类的,分析方法createAdaptiveExtensionClassCode()可知,
通过编程的方式创建了适配类,然后在该类里实现了方法适配,可以看一下为Protocol
创建的适配类Protocol$Adaptive,如下(适配类的部分源码截图)
很清晰可以看出,url对象在其中扮演这重要角色,它决定了扩展的加载具体类型
总之,Duubo实现的扩展点加载机制更加灵活,而且对扩展增加了自动添加增强,这里只是对其中重要实现环节
做了一个大概的分析,如果感兴趣可以自己深入分析!