aop实现原理_Dubbo SPI中AOP实现原理
官网:http://dubbo.apache.org/zh-cn/docs/2.7/source_code_guide/dubbo-spi/
从官网说明中我们可以看到,dubbo spi是java spi的一种增强实现,也就是这种spi机制确保了dubbo高扩展的能力。
说明
dubbo spi增强的实现中包含了ioc和aop的实现,本篇主要讲解aop的实现原理。
- ioc即依赖注入,dubbo spi中可以注入普通的类和spring bean
- aop即面向切面编程,用过spring的应该都知道
实现原理
包装类(Wrap类)
public class A implements I { private I i; public A(I i) { this.i = i; }}
上面这种类就是Wrap 类,即父类是自己的成员变量,把父类当作构造函数的参数传进来。
Dubbo中一些Wrap类如下:
public class QosProtocolWrapper implements Protocol { private Protocol protocol; public QosProtocolWrapper(Protocol protocol) { this.protocol = protocol; }}
public class ProtocolListenerWrapper implements Protocol { private Protocol protocol; public ProtocolListenerWrapper(Protocol protocol) { this.protocol = protocol; }}
扩展点自动包装
我们知道dubbo spi的机制是运行期间寻找具体的实现类,Protocol有很多实现类,如下:
扩展点实现
默认的协议使用的dubbo
@SPI("dubbo")public interface Protocol {
那么运行期间根据URL获取Protocol实例时默认就是DubboProtocol
ExtensionLoader.getExtensionLoader(Protocol.class).getAdaptiveExtension();
但是真正获取的可能不是DubboProtocol,而且增强后的包装类,从源码中我们来分析:
private T createExtension(String name, boolean wrap) { // 1. getExtensionClasses()加载所有的实现类 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, clazz.newInstance()); instance = (T) EXTENSION_INSTANCES.get(clazz); } // 2. 依赖注入 injectExtension(instance); if (wrap) { // 3.包装类排序 List> wrapperClassesList = new ArrayList<>(); if (cachedWrapperClasses != null) { wrapperClassesList.addAll(cachedWrapperClasses); wrapperClassesList.sort(WrapperComparator.COMPARATOR); Collections.reverse(wrapperClassesList); } // 4. AOP实现 if (CollectionUtils.isNotEmpty(wrapperClassesList)) { for (Class> wrapperClass : wrapperClassesList) { Wrapper wrapper = wrapperClass.getAnnotation(Wrapper.class); if (wrapper == null || (ArrayUtils.contains(wrapper.matches(), name) && !ArrayUtils.contains(wrapper.mismatches(), name))) { instance = injectExtension((T) wrapperClass.getConstructor(type).newInstance(instance)); } } } } initExtension(instance); return instance; } catch (Throwable t) { throw new IllegalStateException("Extension instance (name: " + name + ", class: " + type + ") couldn't be instantiated: " + t.getMessage(), t); } }
1.获取所有的实现类
ExtensionLoader初始化的时候会从多个地方获取实现类,然后缓存起来
- META-INF/dubbo/internal/
- META-INF/dubbo/
- META-INF/services/
其中loadClass的时候会找到Wrap Class,然后缓存到cachedWrapperClasses
2.依赖注入
注入依赖的实例
3.包装类排序
sort by sort desc
4.AOP实现
这一步就是AOP增强的实现,通过代码我们可以看到:循环把一个实例当作另一个类的构造参数,然后实例化后注入,具体过程如下:
初始化过程
所以,createExtension返回的实例就是 qosProtocolWrapper,所以服务暴露(export)或者调用的时候(ref)顺序就是
qosProtocolWrapper -> protocolFilterWrapper -> protocolListenerWraper -> dubboProtocol ,以此来实现类AOP的功能。
aop实现原理_Dubbo SPI中AOP实现原理相关推荐
- Spring 原理初探——IoC、AOP
前言 众所周知, 现在的 Spring 框架已经成为构建企业级 Java 应用事实上的标准了,众多的企业项目都构建在 Spring 项目及其子项目之上,特别是 Java Web 项目. Spring ...
- spring系列-注解驱动原理及源码-AOP使用及源码解析
目录 一.用注解方式开启AOP 1.实例 2.AOP简单小结 二.AOP原理 1.@EnableAspectJAutoProxy溯源 2.AnnotationAwareAspectJAutoProxy ...
- aop实现原理_从宏观的实现原理和设计本质入手,带你理解 AOP 框架的原理
点击上方"Java知音",选择"置顶公众号" 技术文章第一时间送达! 作者:FeelsChaotic juejin.im/post/5c57b2d5e51d45 ...
- spring aop 必须的包 及里面用到的东西_Spring 原理初探——IoC、AOP
前言 众所周知, 现在的 Spring 框架已经成为构建企业级 Java 应用事实上的标准了,众多的企业项目都构建在 Spring 项目及其子项目之上,特别是 Java Web 项目. Spring ...
- spring AOP中 aop:advisor 与 aop:aspect 的区别
在开发过程中,不少有Spring Aop的使用, 在面向切面编程时,我们会使用< aop:aspect>: 在进行事务管理时,我们会使用< aop:advisor>. 那么,对 ...
- Spring事务原理深入解析(AOP,Threadlocal, 隔离级别,传播级别)
文章目录 一.摘要 二.基础知识介绍 2.1 JDBC 2.1.1 简单示例 2.1.2 JDBC事务存在的问题: 2.1.2 Spring事务解决该问题的方式 2.2 AOP设计思想 2.2.1 代 ...
- Spring中AOP相关的API及源码解析,原来AOP是这样子的
前言 之所以写这么一篇文章主要是因为下篇文章将结束Spring启动整个流程的分析,从解析配置到创建对象再到属性注入最后再将创建好的对象初始化成为一个真正意义上的Bean.因为下篇文章会涉及到AOP,所 ...
- Spring 2.X 中AOP的简明教程
和Spring1.X相比,Spring2.X使用AspectJ的语法来声明AOP,这使得它更"标准",更灵活了.还是那句话,如果你不了解AspectJ并且打算使用Spring2.X ...
- spring --aop(日志记录)在工程中实际使用
2019独角兽企业重金招聘Python工程师标准>>> ###1.日志切面 package com.readygo.zbhealth.common;import java.util. ...
最新文章
- (19)Reactor Processors——响应式Spring的道法术器
- C 语言编程 — 输入/输出与文件操作
- linux:uabntu日常操作
- 【读书笔记】基础博弈知识小结
- Spring如何加载XSD文件
- android高仿天天动听,Android仿天天动听歌曲自动滚动view
- Python学习-第3课(函数作用域、列表集合字典元祖)
- 估计理论(1):最小方差无偏估计(第2章)
- Transformations in signals and systems DSP
- HTML怎么消除链接下划线,HTML怎么去掉超链接的下划线
- 站在思想层面看MVX架构
- ZigBee技术[转]
- 今天是星期一,两天后是星期三,5天后是星期六;今天是星期六,3天后是星期二。
- vue常用插件(一)
- 标题:深度分销的方向和尺度 内容:Pnbsp;深度分销的方向和尺度BRnbsp;nbsp; 所谓深度分销,有人也称之为通路精耕细作,是通过减少原有渠道层次,并增强中间商分销能力或通过企
- 苹果系统 python闪退怎么解决_MacOS pyinstaller 打包python应用闪退问题解决
- ImageGP/BIC无代码绘制差异基因火山图
- 京东金融支持的银行卡只有几张
- ubuntu/linux安装Atom
- 用Python搭建简单自动化报表(漏斗模型)