dubbo源码分析6——SPI机制中的AOP
在 ExtensionLoader 类的loadFile方法中有下图的这段代码:
类如现在这个ExtensionLoader中的type 是Protocol.class,也就是SPI接口的实现类中XxxProtocol类中有这样的构造函数 public XxxProtocol ( Protocol object) ,这个构造函数显然说明XxxProtocol有包装或代理这个object的意思。所以当发现了这样特点的实现类后,就会把它缓存到wrappers这个变量中,最终缓存在ExtensionLoader的实例属性 cachedWrapperClasses中。
真正进行AOP切面包装的代码是在 createExtension方法中,标红的这段代码:
private T createExtension(String name) {
Class<?> clazz = getExtensionClasses().get(name);
if (clazz == null) {
throw findException(name);
}
try {
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)); //用wrapper类的实例代替原有的instance ,但注意原有的instance作为wrapper的构造参数传入其内部了
}
}
return instance;
} catch (Throwable t) {
throw new IllegalStateException("Extension instance(name: " + name + ", class: " +
type + ") could not be instantiated: " + t.getMessage(), t);
}
}
下面通过一个实例来分析下,看这段代码:
@Test
public void test(){
ExtensionLoader extensionLoader = ExtensionLoader.getExtensionLoader(Protocol.class) ;
Protocol protocol = (Protocol) extensionLoader.getExtension("dubbo") ;
System.out.println(protocol );
}
上面这段代码执行后我们会发现输出的对象的类名是com.alibaba.dubbo.rpc.protocol.ProtocolFilterWrapper,显然得到的protocol对象已经是经过包装了,而且是有两个包装对象类:
com.alibaba.dubbo.rpc.protocol.ProtocolFilterWrapper 和 com.alibaba.dubbo.rpc.protocol.ProtocolListenerWrapper ,打开这两个类的源码,我们会发现它们都会有带Protocol参数的构造函数
public ProtocolListenerWrapper(Protocol protocol){
if (protocol == null) {
throw new IllegalArgumentException("protocol == null");
}
this.protocol = protocol;
} public ProtocolFilterWrapper(Protocol protocol){
if (protocol == null) {
throw new IllegalArgumentException("protocol == null");
}
this.protocol = protocol;
}
所以当我们获取Protocol的某个实现时,就会被这两个类所包装。
dubbo源码分析6——SPI机制中的AOP的更多相关文章
- dubbo源码分析2——SPI机制中的SPI实现类的读取和预处理
SPI机制中的SPI实现类的读取和预处理是由ExtensionLoader类的loadFile方法来完成的 loadFile方法的作用是读取dubbo的某个SPI接口的spi描述文件,然后进行缓存,缓 ...
- dubbo源码分析3——SPI机制中的ExtensionLoader类的objectFactory属性分析
ExtensionLoader类是整个SPI的核心类,每个SPI都会对应一个ExtensionLoader类实例,这个类的构造方法如下: private ExtensionLoader(Class&l ...
- Dubbo源码分析之 SPI(一)
一.概述 dubbo SPI 在dubbo的作用是基础性的,要想分析研究dubbo的实现原理.dubbo源码,都绕不过 dubbo SPI,掌握dubbo SPI 是征服dubbo的必经之路. 本篇文 ...
- Dubbo源码分析之SPI(二)
一.概述 本篇文章是dubbo SPI源码分析的第二篇,接着第一篇继续分析dubbo SPI的内容,我们主要介绍 getDefaultExtension() 获取默认扩展点方法. 由于此方法比较简单, ...
- dubbo源码分析5——SPI机制_AdaptiveExtension的原理和作用
private T createAdaptiveExtension() { try { return injectExtension((T) getAdaptiveExtensionClass().n ...
- dubbo源码分析4——SPI机制_ExtensionFactory类的作用
ExtensionFactory的源码: @SPI public interface ExtensionFactory { /** * Get extension. * * @param type o ...
- dubbo源码分析1——SPI机制的概要介绍
插件机制是Dubbo用于可插拔地扩展底层的一些实现而定制的一套机制,比如dubbo底层的RPC协议.注册中心的注册方式等等.具体的实现方式是参照了JDK的SPI思想,由于JDK的SPI的机制比较简单, ...
- Dubbo源码分析之SPI(三)
一.概述 本篇介绍自适应扩展,方法getAdaptiveExtension()的实现.ExtensionLoader类本身很多功能也使用到了自适应扩展.包括ExtensionFactory扩展. 通俗 ...
- dubbo源码分析6-telnet方式的管理实现
dubbo源码分析1-reference bean创建 dubbo源码分析2-reference bean发起服务方法调用 dubbo源码分析3-service bean的创建与发布 dubbo源码分 ...
随机推荐
- C++ 容器之 list的使用
1.List 装入引用或指针的方式 push_back() push_front() pop_back() pop_front() #include <iostream> #include ...
- R语言学习网址
1. https://www.r-bloggers.com/ 2. https://www.kaggle.com/datasets 3. RStudio download: https://www.r ...
- MyBatis-注解方式整合SSM
Spring.Spring MVC.MyBatis 整合 一.依赖 <?xml version="1.0" encoding="UTF-8"?> & ...
- 14、JDBC-DbUtils-API
DbUtils /** * DbUtils :提供如关闭连接.装载 JDBC 驱动等操作的工具类,里面方法都是静态的. * * public static void close(…) throws j ...
- linux下使用sftp【转】
. 本文完全引用自: http://www.cnblogs.com/kaituorensheng/p/5797753.html 何为sftp sftp是Secure File Transfer Pro ...
- C# 一个特别不错的http请求类
using System; using System.Collections; using System.Collections.Generic; using System.Collections.S ...
- css的几个小技巧
本文收录css设置样式的一些小技巧 1. 设置文字在块级标签居中(包括水平居中和垂直居中) 水平居中 方法一:使用text-align text-align:center 方法二:目标标签的父级标签设 ...
- 开源框架.netCore DncZeus学习(五)下拉树的实现
千里之行,始于足下,先从一个小功能研究起,在菜单管理页面有一个下拉树,先研究下它怎么实现的 1.先找到menu.vue页面 惯性思维先搜索请选择三个字,原来是动态生成的 再向上找DropDown组件, ...
- DataTabe使用Linq实现 Group
DataTable dt = dataSet.Tables[]; var query = from t in dt.AsEnumerable() group t by new { t1 = t.Fie ...
- Mysql宽字节注入(转)
尽管现在呼吁所有的程序都使用unicode编码,所有的网站都使用utf-8编码,来一个统一的国际规范.但仍然有很多,包括国内及国外(特别是非英语国家)的一些cms,仍然使用着自己国家的一套编码,比如g ...