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框架中用到的扩展点。

   继续分析上面代码重要细节:

    

 

 

 

posted on 2021-08-04 21:23  池塘里洗澡的鸭子  阅读(142)  评论(0编辑  收藏  举报