zoukankan      html  css  js  c++  java
  • dubbo源码分析6——SPI机制中的AOP

    在 ExtensionLoader 类的loadFile方法中有下图的这段代码:

    类如现在这个ExtensionLoader中的type 是Protocol.class,也就是SPI接口的实现类中XxxProtocol类中有这样的构造函数 public XxxProtocol ( Protocol  object) ,这个构造函数显然说明XxxProtocol有包装或代理这个object的意思。所以当发现了这样特点的实现类后,就会把它缓存到wrappers这个变量中,最终缓存在ExtensionLoader的实例属性 cachedWrapperClasses中。

    真正进行AOP切面包装的代码是在 createExtension方法中,标红的这段代码:

     private T createExtension(String name) {
            Class<?> clazz = getExtensionClasses().get(name);
            if (clazz == null) {
                throw findException(name);
            }
            try {
                T instance = (T) EXTENSION_INSTANCES.get(clazz);
                if (instance == null) {
                    EXTENSION_INSTANCES.putIfAbsent(clazz, (T) clazz.newInstance());
                    instance = (T) EXTENSION_INSTANCES.get(clazz);
                }
                injectExtension(instance);
                Set<Class<?>> wrapperClasses = cachedWrapperClasses;
                if (wrapperClasses != null && wrapperClasses.size() > 0) {
                    for (Class<?> wrapperClass : wrapperClasses) {
                        instance = injectExtension((T) wrapperClass.getConstructor(type).newInstance(instance));   //用wrapper类的实例代替原有的instance ,但注意原有的instance作为wrapper的构造参数传入其内部了
                    }
                }
                return instance;
            } catch (Throwable t) {
                throw new IllegalStateException("Extension instance(name: " + name + ", class: " +
                        type + ")  could not be instantiated: " + t.getMessage(), t);
            }
        }

    下面通过一个实例来分析下,看这段代码:

    @Test
        public void test(){
            ExtensionLoader extensionLoader = ExtensionLoader.getExtensionLoader(Protocol.class) ;
            Protocol protocol = (Protocol) extensionLoader.getExtension("dubbo") ;
            System.out.println(protocol ); 
        }

    上面这段代码执行后我们会发现输出的对象的类名是com.alibaba.dubbo.rpc.protocol.ProtocolFilterWrapper,显然得到的protocol对象已经是经过包装了,而且是有两个包装对象类:

        com.alibaba.dubbo.rpc.protocol.ProtocolFilterWrapper 和 com.alibaba.dubbo.rpc.protocol.ProtocolListenerWrapper ,打开这两个类的源码,我们会发现它们都会有带Protocol参数的构造函数

    public ProtocolListenerWrapper(Protocol protocol){
            if (protocol == null) {
                throw new IllegalArgumentException("protocol == null");
            }
            this.protocol = protocol;
        }
    
    
    public ProtocolFilterWrapper(Protocol protocol){
            if (protocol == null) {
                throw new IllegalArgumentException("protocol == null");
            }
            this.protocol = protocol;
        }

    所以当我们获取Protocol的某个实现时,就会被这两个类所包装。

  • 相关阅读:
    python之scrapy篇(三)
    python之scrapy篇(二)
    python之scrapy篇(一)
    matlib调用python时转py格式为matlib格式
    ubuntu18.40 rtx2080ti安装显卡驱动/cuda/cudnn/tensorflow-gpu
    pytorch导入错误so: undefined symbol: _Z11libshm_initPKc
    yolo_v3训练自己的模型(人脸及deep-sort)(或自己数据集)
    python-图像处理(映射变换)
    python编译pyc工程--导包问题解决
    python(leetcode)-14最长公共前缀
  • 原文地址:https://www.cnblogs.com/hzhuxin/p/7576164.html
Copyright © 2011-2022 走看看