第四章 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結束。 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM