第四章 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結束。
第四章 dubbo內核之aop源碼解析