读懂Spring AOP中通知的执行原理
前言
这个代理类是AOP基于JDK动态代理生成的,当使用代理类调用目标方法时,会执行到org.springframework.aop.framework.JdkDynamicAopProxy#invoke方法中去,后面的调用链也在这里面。
定义一个切面
切面包含了环绕通知(前)、前置通知、增强方法、环绕通知(后、后置通知、带返回值后置通知、异常通知
/**
* 增强计算器的切面
*/
@Component
@Aspect
public class JisuanqiAspect {
//AOP功能==》引入方式的使用
/* @DeclareParents(value = "yuanma.leiqiang.aop.JiSuanQiImpl",
defaultImpl = YinruImpl.class
)
public static Yinru yinru;*/
//各种通知的使用↓
@Pointcut("execution(* com.redis.aop..*(..))")
public void pointCut() {}
@Before(value = "pointCut()")
public void before(JoinPoint joinPoint) throws Exception{
String name = joinPoint.getSignature().getName();
System.out.println("Before增强了方法"+ name);
}
@After(value = "pointCut()")
public void after(JoinPoint joinPoint) throws Exception{
String name = joinPoint.getSignature().getName();
System.out.println("无返回值After增强了方法"+ name);
}
@AfterReturning(value = "pointCut()", returning = "result")
public void afterReturning(JoinPoint joinPoint, Object result) throws Exception{
String name = joinPoint.getSignature().getName();
System.out.println("带返回值After增强了方法"+ name + "结果为"+result);
}
@AfterThrowing(value = "pointCut()")
public void afterThrowing(JoinPoint joinPoint) throws Exception{
String name = joinPoint.getSignature().getName();
System.out.println("方法出现了异常"+ name);
}
@Around(value = "pointCut()")
public Object around(ProceedingJoinPoint pjp) throws Throwable{
String name = pjp.getSignature().getName();
System.out.println("环绕通知=>方法执行前"+ name);
Object object = pjp.proceed(pjp.getArgs());//执行我们的方法
System.out.println("环绕通知=>方法执行后"+ name);
return object;
}
}
执行结果
上图中有3张图,上面2张为控制台打印的AOP各种类型通知的执行顺序
上两图介绍
图1为执行了异常通知的打印结果:环绕通知(前)→前置通知→增强方法→后置通知→异常通知
图2为正常的结果:环绕通知(前)→前置通知→增强方法→环绕通知(后)→后置通知→带返回值后置通知
可以看出当出现异常后,那种通知是不会被执行的
第三张图
这个图为AOP生成代理类后,使用代理类调用目标方法时执行通知的集合,就是chain集合中的通知会被递归调用,这些方法中看名字就知道是AOP对各个通知方法的调用;