zoukankan      html  css  js  c++  java
  • 05_dubbo_aop

    【对这行代码进行源码分析】

    ExtensionLoader<Protocol> loader = ExtensionLoader.getExtensionLoader(Protocol.class);
    final Protocol dubboProtocol = loader.getExtension("dubbo");  //要分析的源码
    final Protocol adaptiveExtension = loader.getAdaptiveExtension();

    【对上面第二行代码进行源码分析】

    先看下第一行代码执行后的ExtensionLoader实例化的结果

    其中

    * type =interface com.alibaba.dubbo.rpc.Protocol

    * ExtensionFactory objectFactory = AdaptiveExtensionFactory(适配类)

         * AdaptiveExtensionFactory成员变量factories = [ SpringExtensionFactory实例,SpiExtensionFactory实例 ]

    【 getExtension(String name)调用流程 】

    ExtensionLoader<Protocol> loader = ExtensionLoader.getExtensionLoader(Protocol.class);
    final Protocol dubboProtocol = loader.getExtension("dubbo");
    --createExtension(name);
    ----getExtensionClasses() //获取扩展类
    ------loadExtensionClasses()
    --------loadFile(Map<String, Class<?>> extensionClasses, String dir)
    //ioc属性注入
    ----injectExtension(instance); //aop+ioc属性注入 aop获得一个wrapper装饰类
    ----instance = injectExtension((T) wrapperClass.getConstructor(type).newInstance(instance));

    【 createExtension(String name)源码 】

    private T createExtension(String name) {
        /**
         * 从Holder<Map<String, Class<?>>>cachedClasses缓存中获取所有的实现类map,
         * 然后通过name获取到对应的实现类(此时只是一个对象实例,还没有属性注入)
         */
        Class<?> clazz = getExtensionClasses().get(name);
        if (clazz == null) {
            throw findException(name);
        }
        try {
            /**
             * 从 ConcurrentMap<Class<?>, Object> EXTENSION_INSTANCES 类缓存中获取到对应的实现类的Class对象,
             * 如果没有,直接创建,之后放入缓存
             */
            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));
                }
            }
            return instance;
        } catch (Throwable t) {
            throw new IllegalStateException("Extension instance(name: " + name + ", class: " +
                    type + ")  could not be instantiated: " + t.getMessage(), t);
        }
    }

    回头看下META-INF/dubbo/internal/com.alibaba.dubbo.rpc.Protocol文件内容

    registry=com.alibaba.dubbo.registry.integration.RegistryProtocol
    dubbo=com.alibaba.dubbo.rpc.protocol.dubbo.DubboProtocol
    filter=com.alibaba.dubbo.rpc.protocol.ProtocolFilterWrapper
    listener=com.alibaba.dubbo.rpc.protocol.ProtocolListenerWrapper
    mock=com.alibaba.dubbo.rpc.support.MockProtocol
    injvm=com.alibaba.dubbo.rpc.protocol.injvm.InjvmProtocol
    rmi=com.alibaba.dubbo.rpc.protocol.rmi.RmiProtocol
    hessian=com.alibaba.dubbo.rpc.protocol.hessian.HessianProtocol
    com.alibaba.dubbo.rpc.protocol.http.HttpProtocol
    com.alibaba.dubbo.rpc.protocol.webservice.WebServiceProtocol
    thrift=com.alibaba.dubbo.rpc.protocol.thrift.ThriftProtocol
    memcached=com.alibaba.dubbo.rpc.protocol.memcached.MemcachedProtocol
    
    redis=com.alibaba.dubbo.rpc.protocol.redis.RedisProtocol

    com.alibaba.dubbo.rpc.protocol.ProtocolFilterWrapper和com.alibaba.dubbo.rpc.protocol.ProtocolListenerWrapper,这两个类不含有@Adaptive注解且含有Protocol的单参数构造方法,符合这2个条件的类会被列入AOP增强类,会被防止在ExtensionLoader的实例缓存Set<Class<?>> cachedWrapperClasses;中。

    此时的loader:

    * type =interface com.alibaba.dubbo.rpc.Protocol

    * ExtensionFactory objectFactory = AdaptiveExtensionFactory(适配类)

         * AdaptiveExtensionFactory成员变量factories = [ SpringExtensionFactory实例,SpiExtensionFactory实例 ]

    * cachedWrapperClasses = [ class ProtocolListenerWrapper, class ProtocolFilterWrapper ]

    再来看createExtension(String name )中的aop红色部分代码,即dubbo的aop部分。

    Set<Class<?>> wrapperClasses = cachedWrapperClasses;
    if (wrapperClasses != null && wrapperClasses.size() > 0) {
        for (Class<?> wrapperClass : wrapperClasses) {
            instance = injectExtension((T) wrapperClass.getConstructor(type).newInstance(instance));
        }
    }

    在cachedWrapperClasses中缓存两个AOP增强类:ProtocolListenerWrapper和ProtocolFilterWrapper。

    首先获取ProtocolListenerWrapper的单参数构造方法,然后创建ProtocolWrapper实例,最后完成对ProtocolListenerWrapper实例的属性注入,注意此时的instance = ProtocolListenerWrapper实例,而不是之前的DubboProtocol实例,之后使用ProtocolFilterWrapper以同样的方式进行包装,只是此时的ProtocolFilterWrapper包装的是ProtocolListenerWrapper实例。

    instance = ProtocolFilterWrapper实例{
        protocol = ProtocolListenerWrapper实例{
            protocol = DubboProtocol实例
        }
    }

    【 ProtocolListenerWrapper源码 】

    /**
     * ListenerProtocol
     *
     * @author william.liangf
     */
    public class ProtocolListenerWrapper implements Protocol {
    
        private final Protocol protocol;
    
        public ProtocolListenerWrapper(Protocol protocol) {
            if (protocol == null) {
                throw new IllegalArgumentException("protocol == null");
            }
            this.protocol = protocol;
        }
    
        public int getDefaultPort() {
            return protocol.getDefaultPort();
        }
    
        public <T> Exporter<T> export(Invoker<T> invoker) throws RpcException {
            if (Constants.REGISTRY_PROTOCOL.equals(invoker.getUrl().getProtocol())) {
                return protocol.export(invoker);
            }
            return new ListenerExporterWrapper<T>(protocol.export(invoker),
                    Collections.unmodifiableList(ExtensionLoader.getExtensionLoader(ExporterListener.class)
                            .getActivateExtension(invoker.getUrl(), Constants.EXPORTER_LISTENER_KEY)));
        }
    
        public <T> Invoker<T> refer(Class<T> type, URL url) throws RpcException {
            if (Constants.REGISTRY_PROTOCOL.equals(url.getProtocol())) {
                return protocol.refer(type, url);
            }
            return new ListenerInvokerWrapper<T>(protocol.refer(type, url),
                    Collections.unmodifiableList(
                            ExtensionLoader.getExtensionLoader(InvokerListener.class)
                                    .getActivateExtension(url, Constants.INVOKER_LISTENER_KEY)));
        }
    
        public void destroy() {
            protocol.destroy();
        }
    
    }

    【 ProtocolFilterWrapper源码 】

    /**
     * ListenerProtocol
     *
     * @author william.liangf
     */
    public class ProtocolFilterWrapper implements Protocol {
    
        private final Protocol protocol;
    
        public ProtocolFilterWrapper(Protocol protocol) {
            if (protocol == null) {
                throw new IllegalArgumentException("protocol == null");
            }
            this.protocol = protocol;
        }
    
        private static <T> Invoker<T> buildInvokerChain(final Invoker<T> invoker, String key, String group) {
            Invoker<T> last = invoker;
            List<Filter> filters = ExtensionLoader.getExtensionLoader(Filter.class).getActivateExtension(invoker.getUrl(), key, group);
            if (filters.size() > 0) {
                for (int i = filters.size() - 1; i >= 0; i--) {
                    final Filter filter = filters.get(i);
                    final Invoker<T> next = last;
                    last = new Invoker<T>() {
    
                        public Class<T> getInterface() {
                            return invoker.getInterface();
                        }
    
                        public URL getUrl() {
                            return invoker.getUrl();
                        }
    
                        public boolean isAvailable() {
                            return invoker.isAvailable();
                        }
    
                        public Result invoke(Invocation invocation) throws RpcException {
                            return filter.invoke(next, invocation);
                        }
    
                        public void destroy() {
                            invoker.destroy();
                        }
    
                        @Override
                        public String toString() {
                            return invoker.toString();
                        }
                    };
                }
            }
            return last;
        }
    
        public int getDefaultPort() {
            return protocol.getDefaultPort();
        }
    
        public <T> Exporter<T> export(Invoker<T> invoker) throws RpcException {
            if (Constants.REGISTRY_PROTOCOL.equals(invoker.getUrl().getProtocol())) {
                return protocol.export(invoker);
            }
            return protocol.export(buildInvokerChain(invoker, Constants.SERVICE_FILTER_KEY, Constants.PROVIDER));
        }
    
        public <T> Invoker<T> refer(Class<T> type, URL url) throws RpcException {
            if (Constants.REGISTRY_PROTOCOL.equals(url.getProtocol())) {
                return protocol.refer(type, url);
            }
            return buildInvokerChain(protocol.refer(type, url), Constants.REFERENCE_FILTER_KEY, Constants.CONSUMER);
        }
    
        public void destroy() {
            protocol.destroy();
        }
    
    }

    【结果】

    最后返回的instance是ProtocolFilterWrapper对象,

    final Protocol dubboProtocol = loader.getExtension("dubbo");

    这句代码最后的dubboProtocol是ProtocolFilterWrapper实例。

    【参考文章】

    https://www.cnblogs.com/java-zhao/p/7478136.html

  • 相关阅读:
    软件工程实践第三次作业——原型设计
    第三次作业补充
    软件工程实践之词频统计
    软工实践第一次作业
    B*树索引结构和内部管理(转)
    MySQL索引背后的数据结构及算法原理(转)
    Java编程军规
    差分隐私学习三:实现机制
    万能头文件#include <bits/stdc++.h>
    微信小程序-flex布局中align-items和align-self区别
  • 原文地址:https://www.cnblogs.com/HigginCui/p/9610192.html
Copyright © 2011-2022 走看看