Spring中AOP源码剖析

本文详细分析了Spring AOP中后置处理器的工作原理,揭示了如何在AopBean的test()方法执行后进行增强,并重点介绍了最终增强通过递归调用实现的过程。

Spring中AOP源码剖析


关键词

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

一、环境准备

1.1 bean和接口

public class AopBean implements AopBeanInfo{

	@Override
	public 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/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/aop
        https://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
	 */
	@Test
	public 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. 最终增强是通过递归调用,层层增强
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

穿城大饼

你的鼓励将是我最大的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值