zoukankan      html  css  js  c++  java
  • Dubbo的SPI可扩展机制的源码分析

             Dubbo的代码的版本是2.7.0

           在看Dubbo源码的时候,总是出现下面的代码去加载一个类。 

              然后,看一下ProxyFactory这个类名上了加了一个注解。,

               

           这里以ServiceConfig里的ProxyFactory为例,这里就是今天所要讲的Dubbo的SPI机制, 通过ExtensionLoader这个类去实现的。

                 

             这里最主要的的ETENTION_LOADERS是保存扩展点类和对应ExtensionLoader的的映射, EXTENSION_INSTANCES是缓存扩展类和反射实例化的映射,

           getExtensionLoader函数,出入扩展类,如果没有,则放入IINSTENSION_LOADERS里面。映射的value是ExtensionLoader对象,可以看到新建的ExtensioLoader的扩展类

    不是ExtensionFactory,则还是会调用ExtensionLoader.getExtensionLoader(ExtensionFactory.class).getAdaptiveExtension()方法,来加载adaptive的扩展类。

        然后,getAdaptiveExtension的,通过cacheAdaptiveExtension的get方法,  这里可以二次判断来防止的并发的操作。

              因为开始都为空,createAdativeExtension的函数创建一个扩展点的对象。

            然后调用getAdaptiveExtensionClass函数去加载扩展类,

        首先是通过  getExtensionClasses函数,获取扩展点的类

        因为开始都是空的,所以出事调用时候,会调用loadExtensionClasses函数,去加载所有的扩展类,

      

             前面是获取@SPI注解的值,然后loadDirectoy方法去加载项目下 META-INF/dubbo/internal/,META-INF/dubbo/, META-INF/services/

               这里就可以看出META-IN这下面的是都是扩展点的配置。

      

              这里是利用classloade加载class的,还调用loaderResource就是I利用Class.forName去加载对应的类了。

        加载完所有的扩展类后, 初始cacheAdaptiveClass为空,则创建createAdaptiveExtensionClass方法。

       这里首先看一下,createAdapativeExtensionClassCode动态生成的代码,从下面可以看出它生成的类名=扩展类+$Adaptive,实现扩展类的接口,并且找到ClassLoader,并且加载ExtensionLoader的Complier,去编译生成的代码,并且加载到JVM,得到一个Class.

    package org.apache.dubbo.rpc;
    import org.apache.dubbo.common.extension.ExtensionLoader;
    
    public class ProxyFactory$Adaptive implements org.apache.dubbo.rpc.ProxyFactory {
    private static final org.apache.dubbo.common.logger.Logger logger = org.apache.dubbo.common.logger.LoggerFactory.getLogger(ExtensionLoader.class);
    private java.util.concurrent.atomic.AtomicInteger count = new java.util.concurrent.atomic.AtomicInteger(0);
    
    public org.apache.dubbo.rpc.Invoker getInvoker(java.lang.Object arg0, java.lang.Class arg1, org.apache.dubbo.common.URL arg2) throws org.apache.dubbo.rpc.RpcException {
    if (arg2 == null) throw new IllegalArgumentException("url == null");
    org.apache.dubbo.common.URL url = arg2;
    String extName = url.getParameter("proxy", "javassist");
    if(extName == null) throw new IllegalStateException("Fail to get extension(org.apache.dubbo.rpc.ProxyFactory) name from url(" + url.toString() + ") use keys([proxy])");
    org.apache.dubbo.rpc.ProxyFactory extension = null;
     try {
    extension = (org.apache.dubbo.rpc.ProxyFactory)ExtensionLoader.getExtensionLoader(org.apache.dubbo.rpc.ProxyFactory.class).getExtension(extName);
    }catch(Exception e){
    if (count.incrementAndGet() == 1) {
    logger.warn("Failed to find extension named " + extName + " for type org.apache.dubbo.rpc.ProxyFactory, will use default extension javassist instead.", e);
    }
    extension = (org.apache.dubbo.rpc.ProxyFactory)ExtensionLoader.getExtensionLoader(org.apache.dubbo.rpc.ProxyFactory.class).getExtension("javassist");
    }
    return extension.getInvoker(arg0, arg1, arg2);
    }
    public java.lang.Object getProxy(org.apache.dubbo.rpc.Invoker arg0, boolean arg1) throws org.apache.dubbo.rpc.RpcException {
    if (arg0 == null) throw new IllegalArgumentException("org.apache.dubbo.rpc.Invoker argument == null");
    if (arg0.getUrl() == null) throw new IllegalArgumentException("org.apache.dubbo.rpc.Invoker argument getUrl() == null");org.apache.dubbo.common.URL url = arg0.getUrl();
    String extName = url.getParameter("proxy", "javassist");
    if(extName == null) throw new IllegalStateException("Fail to get extension(org.apache.dubbo.rpc.ProxyFactory) name from url(" + url.toString() + ") use keys([proxy])");
    org.apache.dubbo.rpc.ProxyFactory extension = null;
     try {
    extension = (org.apache.dubbo.rpc.ProxyFactory)ExtensionLoader.getExtensionLoader(org.apache.dubbo.rpc.ProxyFactory.class).getExtension(extName);
    }catch(Exception e){
    if (count.incrementAndGet() == 1) {
    logger.warn("Failed to find extension named " + extName + " for type org.apache.dubbo.rpc.ProxyFactory, will use default extension javassist instead.", e);
    }
    extension = (org.apache.dubbo.rpc.ProxyFactory)ExtensionLoader.getExtensionLoader(org.apache.dubbo.rpc.ProxyFactory.class).getExtension("javassist");
    }
    return extension.getProxy(arg0, arg1);
    }
    public java.lang.Object getProxy(org.apache.dubbo.rpc.Invoker arg0) throws org.apache.dubbo.rpc.RpcException {
    if (arg0 == null) throw new IllegalArgumentException("org.apache.dubbo.rpc.Invoker argument == null");
    if (arg0.getUrl() == null) throw new IllegalArgumentException("org.apache.dubbo.rpc.Invoker argument getUrl() == null");org.apache.dubbo.common.URL url = arg0.getUrl();
    String extName = url.getParameter("proxy", "javassist");
    if(extName == null) throw new IllegalStateException("Fail to get extension(org.apache.dubbo.rpc.ProxyFactory) name from url(" + url.toString() + ") use keys([proxy])");
    org.apache.dubbo.rpc.ProxyFactory extension = null;
     try {
    extension = (org.apache.dubbo.rpc.ProxyFactory)ExtensionLoader.getExtensionLoader(org.apache.dubbo.rpc.ProxyFactory.class).getExtension(extName);
    }catch(Exception e){
    if (count.incrementAndGet() == 1) {
    logger.warn("Failed to find extension named " + extName + " for type org.apache.dubbo.rpc.ProxyFactory, will use default extension javassist instead.", e);
    }
    extension = (org.apache.dubbo.rpc.ProxyFactory).getExtensionLoader(org.apache.dubbo.rpc.ProxyFactory.class).getExtension("javassist");
    }
    return extension.getProxy(arg0);
    }
    }
    

     总结:

           本次对Dubbo 的SPI机制的一点粗略的理解。

  • 相关阅读:
    Delphi三层开发小技巧:TClientDataSet的Delta妙用
    Delphi ADOQuery的速度优化
    delphi ADOQUery中错误解决方法"无法为更新定位行。一些值可能已在最后...
    ClientDataSet中修改,删除,添加数据和Delta属性
    学习 SQL 语句
    Delphi处理数据网格DBGrid的编辑框 获取还没有提交到数据集的字段文本
    移动前端头部标签(HTML5 head meta)
    最全面的前端开发指南
    解决jQuery.live在mobile safari(iphone / ipad / ipod)绑定失败的问题
    jQuery滑动选取数值范围插件
  • 原文地址:https://www.cnblogs.com/xjz1842/p/9876210.html
Copyright © 2011-2022 走看看