Spring中AOP源码剖析


关键词

  • aop的增强发生在后置处理器中(没有循环依赖)
  • 最终增强是通过 递归调用 ,层层增强

一、环境准备

1.1 bean和接口

public class AopBean implements AopBeanInfo{@Overridepublic void test() {System.out.println("spring aop test... ...");}
}
public interface AopBeanInfo {public void test();
}

1.2 横切逻辑

/****/
public class LogUtils {/*** 前置通知*/public void beforeMethod() {System.out.println("前置通知");}/*** 最终通知*/public void alertMethod(){System.out.println("最终通知");}/*** 环绕通知* @param pjp* @return* @throws Throwable*/public Object aroundMethod(ProceedingJoinPoint pjp) throws Throwable{System.out.println("环绕通知-pre");Object proceed = pjp.proceed();System.out.println("环绕通知-after");return proceed;}/*** 异常通知*/public void afterThrowingMethod(){System.out.println("异常通知");}/*** 后置通知*/public void afterReturning(){System.out.println("后置通知");}}

1.3 配置文件:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:aop="http://www.springframework.org/schema/aop"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beanshttps://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/aophttps://www.springframework.org/schema/aop/spring-aop.xsd
"><!--循环依赖问题--><bean id="aopBean" class="com.dabing.source.aop.AopBean"></bean><!--aop配置--><!--横切逻辑--><bean id="logUtils" class="com.dabing.source.aop.LogUtils"></bean><aop:config><aop:aspect ref="logUtils"><aop:before method="beforeMethod" pointcut="execution(public void com.dabing.source.aop.AopBean.test())"/><aop:after method="alertMethod" pointcut="execution(public void com.dabing.source.aop.AopBean.test())"/><aop:around method="aroundMethod" pointcut="execution(public void com.dabing.source.aop.AopBean.test())"/><aop:after-returning method="afterReturning" pointcut="execution(public void com.dabing.source.aop.AopBean.test())"/><aop:after-throwing method="afterThrowingMethod" pointcut="execution(public void com.dabing.source.aop.AopBean.test())"/></aop:aspect></aop:config></beans>

1.4 测试类:

 /*** 测试aop*/@Testpublic void testAop(){ApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath:applicationContext-aop.xml");AopBeanInfo aopBean = applicationContext.getBean(AopBeanInfo.class);aopBean.test();}

1.5 测试结果:

二、源码剖析

2.1 实例化/增强链路构建阶段—源码剖析

在测试方法上添加断点,进行debug调试


在此处的断点设置过滤条件,只关注AopBean的创建流程


设置断点条件

放行

重点关注AopBean的后置处理器的处理流程,因为此案例的AOP增强是在Bean的后置处理器中进行的


在AspectJAwareAdvisorAutoProxyCreator中进行AOP增强

创建代理对象




2.2 执行阶段—源码剖析

1. 执行AopBean的test方法

2. 进入代理对象的invoke方法

3. 获取增强链集合(还有6个需要进行拦截增强的对象,其中5个和aop相关)

4. 递归调用proceed方法

5. 递归调用proceed方法,拦截增强对象(ExposeInvocationInterceptor),执行其invoke方法


此处进行了递归调用:在proceed方法中继续调用proceed方法

6. 递归调用proceed方法,拦截增强对象(MethodBeforeAdviceInterceptor),执行其invoke方法


在前置通知对象中,先执行前置逻辑,在进行后续递归操作


执行前置逻辑


继续进行后续递归操作

7. 递归调用proceed方法,拦截增强对象(AspectJAfterAdvice),执行其invoke方法

在最终通知对象中,先执行递归操作,在进行后续后置逻辑执行

先执行递归操作

8. 递归调用proceed方法,拦截增强对象(AspectJAroundAdvice),执行其invoke方法

执行具体的环绕通知逻辑-pre

继续递归调用

9. 递归调用proceed方法,拦截增强对象(AfterReturningAdviceInterceptor),执行其invoke方法

10. 递归调用proceed方法,拦截增强对象(AspectJAfterThrowingAdvice),执行其invoke方法

执行目标方法






目标方法执行完毕后

递归回后置通知,执行后置通知逻辑







一直往下执行
(执行方法略),直接展示回到环绕通知

一直往下执行
(执行方法略),直接展示回到最终通知

一直往下执行invoke方法(执行方法略),直接展示执行具体最终通知方法

至此,aop的执行过程执行完毕

总结

  1. aop的增强发生在后置处理器中(没有循环依赖)
  2. 最终增强是通过递归调用,层层增强

Spring中AOP源码剖析相关推荐

  1. Spring框架AOP源码剖析

    今天我要和大家分享的是 AOP(Aspect-Oriented Programming)这个东西的源码剖析,作为多年的开发者,想必大家在面试的时候都被问过,你知道Spring框架AOP的底层实现机制吗 ...

  2. 动态代理以及对应Spring中AOP源码分析

    AOP(面向切面编程)在Spring中是被广泛应用的(例如日志,事务,权限等),而它的基本原理便是动态代理. 我们知道动态代理有两种:基于JDK的动态代理以及基于CGlib动态代理.以下是两种动态代理 ...

  3. Spring循环依赖源码剖析

    Spring循环依赖源码剖析 一.场景介绍 二.整理执行流程总结 三.源码分析 编写测试类 /*** 测试循环依赖*/@Testpublic void testCyclicDependence(){A ...

  4. 一箭双雕 刷完阿里P8架构师spring学习笔记+源码剖析,涨薪8K

    关于Spring的叙述: 我之前死磕spring的时候,刷各种资料看的我是一头雾水的,后面从阿里的P8架构师那里拿到这两份资料,从源码到案例详细的讲述了spring的各个细节,是我学Spring的启蒙 ...

  5. Spring中Scope源码分析

    目录 概述 Spring中内置的Scope Scope实现原理分析 Scope接口 Scope注解 ConfigurableBeanFactory接口 BeanDefinition接口 Abstrac ...

  6. failed to open log file_C++中glog源码剖析以及如何设计一个高效 log模块

    每个开发者编程中都会记录log信息,多数人都会使用log第三方库,log库使用起来很方便,但我们也需要了解log系统的原理,这里以glog为例进行分析. 开始 这里不会介绍glog中是如何控制INFO ...

  7. 雷丰阳雷神对spring容器的源码剖析

    Spring容器的refresh()[创建刷新]; 1.prepareRefresh()刷新前的预处理;1).initPropertySources()初始化一些属性设置;子类自定义个性化的属性设置方 ...

  8. 76 张图,剖析 Spring AOP 源码,小白居然也能看懂,大神,请收下我的膝盖!

    下面我会简单介绍一下 AOP 的基础知识,以及使用方法,然后直接对源码进行拆解. 不 BB,上文章目录. 1. 基础知识 1.1 什么是 AOP ? AOP 的全称是 "Aspect Ori ...

  9. Spring AOP 源码分析 - 拦截器链的执行过程

    1.简介 本篇文章是 AOP 源码分析系列文章的最后一篇文章,在前面的两篇文章中,我分别介绍了 Spring AOP 是如何为目标 bean 筛选合适的通知器,以及如何创建代理对象的过程.现在我们的得 ...

最新文章

  1. C语言--测试电脑存储模式(大端存储OR小端存储)
  2. 51Nod 1007 正整数分组(01背包)
  3. linux 入门教程
  4. IPTABLES封闭和开放端口
  5. 当C++爬山壁纸——C++山寨版
  6. Kibana部署及配置(四)
  7. spring boot打包问题,访问问题
  8. 32 - I. 从上到下打印二叉树
  9. C++算法之数据查找的代码
  10. Eclipse环境安装Python插件PyDev
  11. python爬虫菜鸟教程-python爬虫项目(新手教程)之知乎(requests方式)
  12. android自定义悬浮控件
  13. 华为HCIE-CloudComputing备考笔记-2021.10
  14. Python class objects confusing
  15. presenting view controller Vs presented view controller
  16. 淘宝店铺图片轮播在线制作技巧
  17. AutoLeaders——翁恺老师的结构的笔记
  18. 计算机领域区块链是什么是意思,为什么区块链瑞普顿RXP是不可篡改的
  19. 王道书P41 T22(单链表实现)
  20. Linux 服务器挂载移动硬盘进行数据拷贝

热门文章

  1. Quality of Service 0, 1 2
  2. dotnetnuke|dnn 内网实现自动登录
  3. SecureCRT设置
  4. 让VirtualBox虚拟机实现开机自动后台运行
  5. 【笔记】2-SAT (tarjan)
  6. Trade off between bias and variance
  7. CentOS 6.2 Eclipse CDT 开发环境搭建
  8. iOS App图标和启动画面尺寸
  9. Java并发(理论知识)—— 线程安全性
  10. MyEclipse下连接Mysql