Spring中AOP源码剖析
一、环境准备
1 bean和接口
public class AopBean implements AopBeanInfo{
@Override
public void test() {
System.out.println("spring aop test... ...");
}
}
public interface AopBeanInfo {
public void test();
}
2 横切逻辑
public class LogUtils {
public void beforeMethod() {
System.out.println("前置通知");
}
public void alertMethod(){
System.out.println("最终通知");
}
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("后置通知");
}
}
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>
<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>
4 测试类:
@Test
public void testAop(){
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath:applicationContext-aop.xml");
AopBeanInfo aopBean = applicationContext.getBean(AopBeanInfo.class);
aopBean.test();
}
5 测试结果:
二、源码剖析
设置断点条件 放行
递归1-into: 此处进行了递归调用:在proceed方法中继续调用proceed方法
递归2-into:
递归3-into:
总结
- aop的增强发生在后置处理器中(没有循环依赖)
- 最终增强是通过递归调用,层层增强
|