Dubbo源码剖析六之SPI扩展点的实现之getExtensionLoader
Dubbo SPI机制之三Adaptive自适应功能 - 池塘里洗澡的鸭子 - 博客园 (cnblogs.com)中,示例案例中自定义了扩展接口而不是使用Dubbo已提供的扩展接口。在案例中,主程序分别使用了不同的加载方法,如下:
getExtensionLoader:获取扩展点加载器并加载锁对于的所有扩展点实现
getExtension:根据name获取扩展的指定实现
从ExtensionLoader扩展点加载类注释分析:
图中红框中的三个类是配合使用,如果在单进程中存在多dubbo服务应用是需要同时重构这三个类的。同时dubbo扩展点加载要点如下:
1、自动注入依赖的扩展点(springframewok);
2、在包装器中自动包装扩展点;
3、默认扩展需是一个自适应的实例。
DubboSPI机制二之Dubbo中SPI初体验 - 池塘里洗澡的鸭子 - 博客园 (cnblogs.com)中Dubbo中SPI对JDK标准的SPI的一个改进就是:
这个改进点如何体现的呢?通过对dubbo提供的已有的扩展点的使用,即主程序执行的过程中并没有显示调用加载的过程,那就是通过对spring IOC和AOP的支持解决了。跟踪案例源码分析Dubbo扩展点实现过程如下:
一、getExtensionLoader 加载过程
1、实例化ExtensionLoader
跟踪到:
可知,EXTENTION_LOADERS最开始为空,不同类型loaders创建后放至其中缓存汇总。进一步调试跟踪可知,在触发事件之前,非懒加载bean的过程中,相关extentionloader已保存至缓存:
2、具体分析ExtentionLoader的构造方法。其实它比较简单并没有太多的操作,主要是对type进行赋值操作然后获取extensionFactory对象。
是常见的工厂模式,主要是对type进行三目运算符操作,首先获得ExtensionFactory对象——其本身也是一个扩展点的加载。再对具体扩展点加载器进行。
3、具体关注ExtensionFactory做什么工作?其通过传入扩展点类型和真正的名称来获取扩展,这就与SPI中具体名称实现关联了。
4、由于ExtensionFactory本身也是一个扩展点,具体看看dubbo对这个扩展点提供的默认实现
可以看到有两个:一个apative,一个spif分别与注解@adaptive和@SPI挂钩了。至于读取文件的过程,参考Java基于ClassLoder/ InputStream 配合读取配置文件 - 池塘里洗澡的鸭子 - 博客园 (cnblogs.com)。
5、分析默认扩展工厂的具体实现adaptive=org.apache.dubbo.common.extension.factory.AdaptiveExtensionFactory。通过类名基本可知其最主要的作用是代理其他的ExtensionFactory,其中比较重要的方法就是getSupportedExtensions——获取所有支持的或者信息实现。
该类UML图如下:
完成以上操作后,下列ExtentionLoader对象下列属性更新:
1)cachedAdaptiveClass: 当前Extension类型对应的AdaptiveExtension类型(只能一个)
2)cachedWrapperClasses: 当前Extension类型对应的所有Wrapper实现类型(无顺序)
3)cachedActivates: 当前Extension实现自动激活实现缓存(map,无序)
4)cachedNames: 扩展点实现类对应的名称(如配置多个名称则值为第一个)
通过以上调试,扩展点的加载大致流程是:
1)判断扩展点工厂这个扩展点是否加载(是的扩展点工厂也是个扩展点),没有先将这个扩展点加载。
2)利用该扩展点工厂生产Dubbo框架中用到的扩展点。
继续分析上面代码重要细节: