知识章节

基础知识

什么是 AOP

  • AOP 的全称是 “Aspect Oriented Programming”,即面向切面编程
  • 在 AOP 的思想里面,周边功能(比如性能统计,日志,事务管理等)被定义为切面,核心功能和切面功能分别独立进行开发,然后把核心功能和切面功能“编织”在一起,这就叫 AOP
  • AOP 能够将那些与业务无关,却为业务模块所共同调用的逻辑封装起来,便于减少系统的重复代码,降低模块间的耦合度,并有利于未来的可拓展性和可维护性

AOP 基础概念

  • 连接点(Join point):能够被拦截的地方,Spring AOP 是基于动态代理的,所以是方法拦截的,每个成员方法都可以称之为连接点
  • 切点(Poincut):每个方法都可以称之为连接点,我们具体定位到某一个方法就成为切点
  • 增强/通知(Advice):表示添加到切点的一段逻辑代码,并定位连接点的方位信息,简单来说就定义了是干什么的,具体是在哪干
  • 织入(Weaving):将增强/通知添加到目标类的具体连接点上的过程
  • 引入/引介(Introduction):允许我们向现有的类添加新方法或属性,是一种特殊的增强
  • 切面(Aspect):切面由切点和增强/通知组成,它既包括了横切逻辑的定义、也包括了连接点的定义。
  • AOP 五种通知分类

    • 前置通知(Before Advice):在目标方法被调用前调用通知功能
    • 后置通知(After Advice):在目标方法被调用之后调用通知功能
    • 返回通知(After-returning):在目标方法成功执行之后调用通知功能
    • 异常通知(After-throwing):在目标方法抛出异常之后调用通知功能
    • 环绕通知(Around):把整个目标方法包裹起来,在被调用前和调用之后分别调用通知功能

AOP 简单示例

创建一个配置类,开启 AspectJ 的自动代理功能

@Configuration
@EnableAspectJAutoProxy
@ComponentScan("com.aspectj")
public class DemoAspectJConfig {// @EnableAspectJAutoProxy 开启注解 aop 功能// 向 spring 容器中注册 AnnotationAwareAspectJAutoProxyCreator
}

新建接口和接口实现类

// 接口
public interface DemoDao {void query();
}// 实现类
@Component
public class DemoDaoImpl implements DemoDao {@Overridepublic void query() {System.out.println("query ......");}
}

创建一个切面

@Aspect
@Component
public class DemoAspect {// 配置切点@Pointcut("execution(* com.aspectj.dao.*.*(..))")public void point(){}// 切点通知@Before("point()")public void beforeAdd(){System.out.println("before-------------");}
}

创建启动类

public class TestAspect {public static void main(String[] args) {// 刷新容器AnnotationConfigApplicationContext configApplicationContext = new AnnotationConfigApplicationContext(DemoAspectJConfig.class)// 获取 bean 对象DemoDao dao = configApplicationContext.getBean(DemoDao.class);// 代理对象执行dao.query();}
}

启动 main() 方法,可以看到输出的内容,AOP 配置方法执行

Spring AOP 执行流程

源码解读

代码入口





前置处理

判断是否是切面








构建 bean 对象 advisors 流程
① 遍历所有的类
② 判断是否切面,只有切面才会进入后面逻辑
③ 获取每个 Aspect 的切面列表
④ 保存 Aspect 的切面列表到缓存 advisorsCache<beanName,advisors> 中

获取切面列表







到这一步,前置处理已经完成 !

后置处理

获取切面




创建代理对象


对象增强处理流程
① 获取当前 bean 对象 advisors 列表,判断是否为空
② 不为空就创建代理对象
















切面执行



实例化 ReflectiveMethodInvocation 对象,调用 proceed() 方法

第一次递归

数组的第一个对象是 ExposeInvocationInterceptor,执行 invoke(),注意入参是 ReflectiveMethodInvocation

第二次递归

数组的第二个对象是 MethodBeforeAdviceInterceptor,执行 invoke()

第三次递归

如果 advisor 有后置处理,就执行第三次递归

跳出递归

总结

  • AOP 实现原理

    • 将所有的切面都保存在缓存中
    • 取出缓存中的切面列表,和 bean 对象的所有方法匹配,拿到属于 bean 对象的切面列表
    • 创建 AOP 代理对象
    • 通过 “责任链 + 递归”,去执行切面逻辑

Spring AOP 超详细源码解析相关推荐

  1. 深入理解MyBatis一级缓存和二级缓存【超详细源码解析】

    视频地址:https://www.bilibili.com/video/BV1nP411A7Gu MyBatis的缓存是一个常见的面试题 一级缓存的作用域为何是 sqlSession.二级缓存的作用域 ...

  2. spring 注解试事物源码解析

    spring 注解试事物源码解析 基于xml注解式事务入口 public class TxNamespaceHandler extends NamespaceHandlerSupport {stati ...

  3. JUC.Condition学习笔记[附详细源码解析]

    JUC.Condition学习笔记[附详细源码解析] 目录 Condition的概念 大体实现流程 I.初始化状态 II.await()操作 III.signal()操作 3个主要方法 Conditi ...

  4. Spring事件机制Event源码解析(未完待续)

    Spring事件机制Event源码解析(未完待续) 监听器: ApplicationEvent事件 ApplicationListener监听器(观察者) ApplicationEventMultic ...

  5. Spring原理学习系列之三:Spring AOP原理(从源码层面分析)-------上部

    引言 本文是Spring原理分析的第三篇博文,主要阐述Spring AOP相关概念,同时从源码层面分析AOP实现原理.对于AOP原理的理解有利于加深对Spring框架的深入理解.同时我也希望可以探究S ...

  6. Spring之循环依赖源码解析

    目录 1.什么是循环依赖? 2.为什么会出现循环依赖? 3.面对循环依赖问题,我们该如何思考解决? 4.Spring是怎么解决循环依赖的? 5.总结 1.什么是循环依赖? 有两个类Order.Cust ...

  7. weiler-atherton多边形裁剪算法_EAST算法超详细源码解析:数据预处理与标签生成...

    作者简介 CW,广东深圳人,毕业于中山大学(SYSU)数据科学与计算机学院,毕业后就业于腾讯计算机系统有限公司技术工程与事业群(TEG)从事Devops工作,期间在AI LAB实习过,实操过道路交通元 ...

  8. EAST算法超详细源码解析:数据预处理与标签生成

    作者简介 CW,广东深圳人,毕业于中山大学(SYSU)数据科学与计算机学院,毕业后就业于腾讯计算机系统有限公司技术工程与事业群(TEG)从事Devops工作,期间在AI LAB实习过,实操过道路交通元 ...

  9. spring系列-注解驱动原理及源码-AOP使用及源码解析

    目录 一.用注解方式开启AOP 1.实例 2.AOP简单小结 二.AOP原理 1.@EnableAspectJAutoProxy溯源 2.AnnotationAwareAspectJAutoProxy ...

最新文章

  1. 安装MySQL时出现黄色感叹号,提示3306已被占用
  2. 【Linux】Linux中目录结构说明
  3. implementation of UI5 bindAggregation - busyDialog is handled automatically
  4. if else if语句的用法python_Python笔记3---if语句、if-elif-else 结构、使用if语句处理列表...
  5. MySQL的主动优化和被动优化_MySQL“被动”性能优化汇总!
  6. java的或等于_Java中的“小于或等于”比较运算符是__________: !=|||=|=
  7. FineUI表格模板列Undefined问题
  8. apk部分手机安装失败_3关于Apk安装失败问题的解决方法
  9. Python 字典(dict)操作(update)、翻转字典
  10. 【学习OpenCV4】如何操作图像中的像素?
  11. 专利与论文-4:专利申请流程与生命周期及费用
  12. 阿里云短信验证码购教程(Java演示)
  13. Unrecognized Windows Sockets error: 10106: Socket creation failed
  14. python表单数据系统_python 网页提交表单数据库
  15. vue下载后端返回的压缩包
  16. iOS开发——设置支持的iOS设备(512m内存以上设备)
  17. 创业公司 股权分配| 从西少爷股权纷争看初创公司找合伙人与股权分配
  18. 制动电阻器的工作原理及应用特点
  19. Android 应用程序开发
  20. 解决Ubuntu无线网卡突然无法连接

热门文章

  1. 华为社招16级待遇2020_2020上海建桥学院产品设计(珠宝首饰设计)系16级毕业设计作品展(四)...
  2. PhotoShop 矢量蒙板
  3. 拉格朗日中值定理的应用
  4. WordPress修改WordPress地址和站点地址之后无法打开网站和无法后台登录
  5. linux 7 内核崩溃重启,centos7无故重启-内核升级
  6. php的视频怎么保存,premiere怎么保存剪辑好的视频
  7. 手动管理采购订单周期的挑战以及如何应对
  8. 2020年清华伯克利(TBSI)预推免面经
  9. 故事--你不杀伯仁,伯仁确因你而死
  10. Pandas+Pyecharts | 北京某平台二手房数据分析+可视化