此文已由作者赵计刚薪授权网易云社区发布。
欢迎访问网易云社区,了解更多网易技术产品运营经验。
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:
二、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:
再来看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实例。
更多网易技术、产品、运营经验分享请点击。