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

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

05_dubbo_aop的更多相关文章

随机推荐

  1. JDBC完成增加-修改-增加-查询

    JDBC的基本使用流程: 增加    1 导入jar包:        导入ojdbc6.jar,在项目上右键 builder path-->add to builder path.    2 ...

  2. CSS: Multiple Attribute Selector [name="value"][name2="value2"]

    this.document.querySelectorAll('div[id*="dayselector"][class*="x-autocontainer-innerC ...

  3. 「DB」数据库事务的隔离级别

    *博客搬家:初版发布于 2017/04/10 00:37    原博客地址:https://my.oschina.net/sunqinwen/blog/875833 数据库事务的隔离级别 讲事务的隔离 ...

  4. ORM查询练习

    ORM查询练习 Django ORM  ORM查询的练习题 ORM代码 from django.db import models # Create your models here. class Pu ...

  5. 匈牙利算法、KM算法

    PS:其实不用理解透增广路,交替路,网上有对代码的形象解释,看懂也能做题,下面我尽量把原理说清楚 基本概念 (部分来源.部分来源) 二分图: 设G=(V,E)是一个无向图,如果顶点V可分割为两个互不相 ...

  6. 向指定url发送请求与获取响应

    string url = @"https://www.baidu.com"; //向指定服务器发起请求 HttpWebRequest request = (HttpWebReque ...

  7. hive Getting Started

    Apache HiveThe Apache Hive™ data warehouse software facilitates reading, writing, and managing large ...

  8. java中比较两个日期的大小

    String beginTime=new String("2014-08-15 10:22:22"); String endTime=new String("2014-0 ...

  9. vue element 常见问题

    1. vue2.0 给data对象新增属性,并触发视图更新  $set this.$set(this.ossData, "signature", 222) // 正确用法 // 数 ...

  10. flow类型检查

    https://blog.csdn.net/tangxiujiang/article/details/80778627 Flow的简单介绍 2018年06月22日 21:54:25 tangxiuji ...