zoukankan      html  css  js  c++  java
  • 第四章 dubbo内核之aop源码解析

    1         ExtensionLoader<Protocol> loader = ExtensionLoader.getExtensionLoader(Protocol.class);
    2         final Protocol dubboProtocol = loader.getExtension("dubbo");
    3         final Protocol adaptiveExtension = loader.getAdaptiveExtension();

    第一行代码在2.2 dubbo-spi源码解析中讲过,本节来看第二行代码。

    一、获取一个ExtensionLoader

    第一行代码后获得的loader:

    • Class<?> type = interface com.alibaba.dubbo.rpc.Protocol
    • ExtensionFactory objectFactory = AdaptiveExtensionFactory(适配类)
      • factories = [SpringExtensionFactory实例, SpiExtensionFactory实例]

    二、getExtension("dubbo")

    调用层级:

    1 ExtensionLoader<T>.getExtension()
    2 --createExtension(String name)
    3 ----getExtensionClasses().get(name)//获取扩展类
    4 ------loadExtensionClasses()
    5 --------loadFile(Map<String, Class<?>> extensionClasses, String dir)
    6 ----injectExtension(instance);//ioc
    7 ----wrapper包装;//aop

    createExtension(String name),该方法源码如下:

     1     private T createExtension(String name) {
     2         /** 从cachedClasses缓存中获取所有的实现类map,之后通过name获取到对应的实现类的Class对象 */
     3         Class<?> clazz = getExtensionClasses().get(name);
     4         if (clazz == null) {
     5             throw findException(name);
     6         }
     7         try {
     8             /** 从EXTENSION_INSTANCES缓存中获取对应的实现类的Class对象,如果没有,直接创建,之后放入缓存 */
     9             T instance = (T) EXTENSION_INSTANCES.get(clazz);
    10             if (instance == null) {
    11                 EXTENSION_INSTANCES.putIfAbsent(clazz, (T) clazz.newInstance());
    12                 instance = (T) EXTENSION_INSTANCES.get(clazz);
    13             }
    14             injectExtension(instance);
    15             Set<Class<?>> wrapperClasses = cachedWrapperClasses;
    16             if (wrapperClasses != null && wrapperClasses.size() > 0) {
    17                 for (Class<?> wrapperClass : wrapperClasses) {
    18                     instance = injectExtension((T) wrapperClass.getConstructor(type).newInstance(instance));
    19                 }
    20             }
    21             return instance;
    22         } catch (Throwable t) {
    23             throw new IllegalStateException("Extension instance(name: " + name + ", class: " + type
    24                                             + ")  could not be instantiated: " + t.getMessage(),
    25                 t);
    26         }
    27     }

    这里,先给出META-INF/dubbo/internal/com.alibaba.dubbo.rpc.Protocol内容:

     1 registry=com.alibaba.dubbo.registry.integration.RegistryProtocol
     2 dubbo=com.alibaba.dubbo.rpc.protocol.dubbo.DubboProtocol
     3 filter=com.alibaba.dubbo.rpc.protocol.ProtocolFilterWrapper
     4 listener=com.alibaba.dubbo.rpc.protocol.ProtocolListenerWrapper
     5 mock=com.alibaba.dubbo.rpc.support.MockProtocol
     6 injvm=com.alibaba.dubbo.rpc.protocol.injvm.InjvmProtocol
     7 rmi=com.alibaba.dubbo.rpc.protocol.rmi.RmiProtocol
     8 hessian=com.alibaba.dubbo.rpc.protocol.hessian.HessianProtocol
     9 com.alibaba.dubbo.rpc.protocol.http.HttpProtocol
    10 com.alibaba.dubbo.rpc.protocol.webservice.WebServiceProtocol
    11 thrift=com.alibaba.dubbo.rpc.protocol.thrift.ThriftProtocol
    12 memcached=com.alibaba.dubbo.rpc.protocol.memcached.MemcachedProtocol
    13 redis=com.alibaba.dubbo.rpc.protocol.redis.RedisProtocol

    com.alibaba.dubbo.rpc.protocol.ProtocolFilterWrapper和com.alibaba.dubbo.rpc.protocol.ProtocolListenerWrapper,这两个类不含有@Adaptive注解且具有含有Protocol的单参构造器,符合这样条件的会被列入AOP增强类。放置在loader的私有属性cachedWrapperClasses中。

    此时的loader:

    • Class<?> type = interface com.alibaba.dubbo.rpc.Protocol
    • ExtensionFactory objectFactory = AdaptiveExtensionFactory(适配类)
      • factories = [SpringExtensionFactory实例, SpiExtensionFactory实例]
    • cachedWrapperClasses = [class ProtocolListenerWrapper, class ProtocolFilterWrapper]

    再来看createExtension(String name)中的红色部分,就是今天的重点AOP。如上所讲,我在cachedWrapperClasses中缓存了两个AOP增强类:class ProtocolListenerWrapper和class ProtocolFilterWrapper。

    首先是获取ProtocolListenerWrapper的单参构造器,然后创建ProtocolListenerWrapper实例,最后完成对ProtocolListenerWrapper实例进行属性注入,注意此时的instance=ProtocolListenerWrapper实例,而不再是之前的DubboProtocol实例了。之后使用ProtocolFilterWrapper以同样的方式进行包装,只是此时ProtocolFilterWrapper包装的是ProtocolListenerWrapper实例,也就是类似于这样的关系:

    1 instance = ProtocolFilterWrapper实例 {
    2       protocol = ProtocolListenerWrapper实例 {
    3           protocol = DubboProtocol实例
    4       }  
    5 }    

    来看一下ProtocolListenerWrapper源码:

     1 package com.alibaba.dubbo.rpc.protocol;
     2 
     3 import com.alibaba.dubbo.common.Constants;
     4 import com.alibaba.dubbo.common.URL;
     5 import com.alibaba.dubbo.common.extension.ExtensionLoader;
     6 import com.alibaba.dubbo.rpc.Exporter;
     7 import com.alibaba.dubbo.rpc.ExporterListener;
     8 import com.alibaba.dubbo.rpc.Invoker;
     9 import com.alibaba.dubbo.rpc.InvokerListener;
    10 import com.alibaba.dubbo.rpc.Protocol;
    11 import com.alibaba.dubbo.rpc.RpcException;
    12 import com.alibaba.dubbo.rpc.listener.ListenerExporterWrapper;
    13 import com.alibaba.dubbo.rpc.listener.ListenerInvokerWrapper;
    14 
    15 import java.util.Collections;
    16 
    17 public class ProtocolListenerWrapper implements Protocol {
    18     private final Protocol protocol;
    19 
    20     public ProtocolListenerWrapper(Protocol protocol) {
    21         if (protocol == null) {
    22             throw new IllegalArgumentException("protocol == null");
    23         }
    24         this.protocol = protocol;
    25     }
    26 
    27     public int getDefaultPort() {
    28         return protocol.getDefaultPort();
    29     }
    30 
    31     public <T> Exporter<T> export(Invoker<T> invoker) throws RpcException {
    32         if (Constants.REGISTRY_PROTOCOL.equals(invoker.getUrl().getProtocol())) {
    33             return protocol.export(invoker);
    34         }
    35         return new ListenerExporterWrapper<T>(protocol.export(invoker),
    36                 Collections.unmodifiableList(ExtensionLoader.getExtensionLoader(ExporterListener.class)
    37                         .getActivateExtension(invoker.getUrl(), Constants.EXPORTER_LISTENER_KEY)));
    38     }
    39 
    40     public <T> Invoker<T> refer(Class<T> type, URL url) throws RpcException {
    41         if (Constants.REGISTRY_PROTOCOL.equals(url.getProtocol())) {
    42             return protocol.refer(type, url);
    43         }
    44         return new ListenerInvokerWrapper<T>(protocol.refer(type, url),
    45                 Collections.unmodifiableList(
    46                         ExtensionLoader.getExtensionLoader(InvokerListener.class)
    47                                 .getActivateExtension(url, Constants.INVOKER_LISTENER_KEY)));
    48     }
    49 
    50     public void destroy() {
    51         protocol.destroy();
    52     }
    53 }

    这里的方法不做讲解,等到了服务提供者暴露服务和服务消费者引用服务的时候再做讲解。

    ProtocolFilterWrapper源码如下:

     1 package com.alibaba.dubbo.rpc.protocol;
     2 
     3 import com.alibaba.dubbo.common.Constants;
     4 import com.alibaba.dubbo.common.URL;
     5 import com.alibaba.dubbo.common.extension.ExtensionLoader;
     6 import com.alibaba.dubbo.rpc.Exporter;
     7 import com.alibaba.dubbo.rpc.Filter;
     8 import com.alibaba.dubbo.rpc.Invocation;
     9 import com.alibaba.dubbo.rpc.Invoker;
    10 import com.alibaba.dubbo.rpc.Protocol;
    11 import com.alibaba.dubbo.rpc.Result;
    12 import com.alibaba.dubbo.rpc.RpcException;
    13 
    14 import java.util.List;
    15 
    16 public class ProtocolFilterWrapper implements Protocol {
    17     private final Protocol protocol;
    18 
    19     public ProtocolFilterWrapper(Protocol protocol) {
    20         if (protocol == null) {
    21             throw new IllegalArgumentException("protocol == null");
    22         }
    23         this.protocol = protocol;
    24     }
    25 
    26     private static <T> Invoker<T> buildInvokerChain(final Invoker<T> invoker, String key, String group) {
    27         Invoker<T> last = invoker;
    28         List<Filter> filters = ExtensionLoader.getExtensionLoader(Filter.class).getActivateExtension(invoker.getUrl(), key, group);
    29         if (filters.size() > 0) {
    30             for (int i = filters.size() - 1; i >= 0; i--) {
    31                 final Filter filter = filters.get(i);
    32                 final Invoker<T> next = last;
    33                 last = new Invoker<T>() {
    34 
    35                     public Class<T> getInterface() {
    36                         return invoker.getInterface();
    37                     }
    38 
    39                     public URL getUrl() {
    40                         return invoker.getUrl();
    41                     }
    42 
    43                     public boolean isAvailable() {
    44                         return invoker.isAvailable();
    45                     }
    46 
    47                     public Result invoke(Invocation invocation) throws RpcException {
    48                         return filter.invoke(next, invocation);
    49                     }
    50 
    51                     public void destroy() {
    52                         invoker.destroy();
    53                     }
    54 
    55                     @Override
    56                     public String toString() {
    57                         return invoker.toString();
    58                     }
    59                 };
    60             }
    61         }
    62         return last;
    63     }
    64 
    65     public int getDefaultPort() {
    66         return protocol.getDefaultPort();
    67     }
    68 
    69     public <T> Exporter<T> export(Invoker<T> invoker) throws RpcException {
    70         if (Constants.REGISTRY_PROTOCOL.equals(invoker.getUrl().getProtocol())) {
    71             return protocol.export(invoker);
    72         }
    73         return protocol.export(buildInvokerChain(invoker, Constants.SERVICE_FILTER_KEY, Constants.PROVIDER));
    74     }
    75 
    76     public <T> Invoker<T> refer(Class<T> type, URL url) throws RpcException {
    77         if (Constants.REGISTRY_PROTOCOL.equals(url.getProtocol())) {
    78             return protocol.refer(type, url);
    79         }
    80         return buildInvokerChain(protocol.refer(type, url), Constants.REFERENCE_FILTER_KEY, Constants.CONSUMER);
    81     }
    82 
    83     public void destroy() {
    84         protocol.destroy();
    85     }
    86 }

    这里的方法不做讲解,等到了服务提供者暴露服务和服务消费者引用服务的时候再做讲解。

    最后返回的instance是ProtocolFilterWrapper对象,也就是说final Protocol dubboProtocol = loader.getExtension("dubbo");这句代码最后的dubboProtocol是ProtocolFilterWrapper实例。

    至此,aop结束。 

  • 相关阅读:
    Spring_配置 Bean(2)
    Spring_HelloWorld
    搭建 Spring 开发环境
    MongoDB快速入门(十三)- 聚合count、distinct和group
    缓存技术,封装好的缓存类
    HTTP协议详解
    C# 缓存技术
    Web Service 的工作原理
    webview长按保存图片
    android Webview 实现js调用java代码实现Activity跳转
  • 原文地址:https://www.cnblogs.com/java-zhao/p/7478136.html
Copyright © 2011-2022 走看看