美文网首页
11.Dubbo的适配器原理

11.Dubbo的适配器原理

作者: 山海树 | 来源:发表于2020-09-08 07:36 被阅读0次

    适配器模式通过定义一个新的接口(对要实现的功能加以抽象),和一个实现该接口的Adapter(适配器)类来透明地调用外部组件。这样替换外部组件时,最多只要修改几个Adapter类就可以了,其他源代码都不会受到影响。

    从上面的适配器模式定义可以看出,所谓的适配器模式是针对一个接口,通过一个实现类Adapter来动态的替换具体需要的实现类。

    在Dubbo中由于几乎所有的功能点都是由SPI来实现的,因此不可避免的产生的大量的接口和其对应的实现类,因此Dubbo采用适配器模式,来选择具体的业务操作室需要用的的真正的实现类。

    用Protocol接口来说
    在serviceConfig.export()的时候,Dubbo会根据动态编译技术来为Protocol生成一个Protcol$Adaptive的实例对象,该对象是实现了Protocol,其中的export()方法,通过获取Dubbo的URL的protoclo的值,来确定需要用到的具体的实现,

    serviceConfig.export()->protocol.export()->protocol$Adaptive.export()->protocolImpl.export()->打开netty监听,向注册中心发布服务的操作。

    因此在调用Protocol.export()的时候就变成通过适配器来调用真正的实现 的export()方法。

    生成的Protocol代码

    package org.apache.dubbo.rpc;
    import org.apache.dubbo.common.extension.ExtensionLoader;
    public class Protocol$Adaptive implements org.apache.dubbo.rpc.Protocol {
      public void destroy()  {
              throw new UnsupportedOperationException("The method public abstract void org.apache.dubbo.rpc.Protocol.destroy() of interface org.apache.dubbo.rpc.Protocol is not adaptive method!");
      }
      public int getDefaultPort()  {
               throw new UnsupportedOperationException("The method public abstract int org.apache.dubbo.rpc.Protocol.getDefaultPort() of interface org.apache.dubbo.rpc.Protocol is not adaptive method!");
      }
      public org.apache.dubbo.rpc.Exporter export(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.getProtocol() == null ? "dubbo" : url.getProtocol() );
             if(extName == null) throw new IllegalStateException("Failed to get extension (org.apache.dubbo.rpc.Protocol) name from url (" + url.toString() + ") use keys([protocol])");
             org.apache.dubbo.rpc.Protocol extension = (org.apache.dubbo.rpc.Protocol)ExtensionLoader.getExtensionLoader(org.apache.dubbo.rpc.Protocol.class).getExtension(extName);
            return extension.export(arg0);
      }
      public org.apache.dubbo.rpc.Invoker refer(java.lang.Class arg0, org.apache.dubbo.common.URL arg1) throws org.apache.dubbo.rpc.RpcException {
            if (arg1 == null) throw new IllegalArgumentException("url == null");
            org.apache.dubbo.common.URL url = arg1;
            String extName = ( url.getProtocol() == null ? "dubbo" : url.getProtocol() );
            if(extName == null) throw new IllegalStateException("Failed to get extension     (org.apache.dubbo.rpc.Protocol) name from url (" + url.toString() + ") use keys([protocol])");
            org.apache.dubbo.rpc.Protocol extension = (org.apache.dubbo.rpc.Protocol)ExtensionLoader.getExtensionLoader(org.apache.dubbo.rpc.Protocol.class).getExtension(extName);
            return extension.refer(arg0, arg1);
      }
    }
    

    (如果想看到别的SPI的Adaptive可以通过断点查看)


    image.png

    Dubbo中,会给每一个SPI扩展接口都进行此操作

    相关文章

      网友评论

          本文标题:11.Dubbo的适配器原理

          本文链接:https://www.haomeiwen.com/subject/awfcektx.html