网上的一些教程,大多数是拿Spring4.x 跟5.x来对比,其实 这几个通知顺序是从Spring版本为5.2.7.RELEASE---SpringBoot版本为2.2.8.RELEASE时 AOP执行顺序才发生的改变。
Aop常用注解
- @Before 前置通知:目标方法之前执行
- @After 后置通知:目标方法之后执行(始终执行)
- @AfterReturning 返回后通知,执行方法结束前执行执行(异常不执行)
- @AfterThrowing 异常通知:出现异常时执行
- @Around 环绕通知 环绕目标方法执行
新建一个切面类MyAspect并为切面类新增两个注解
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;
@Aspect
@Component
public class MyAspect {
@Before("execution(public int com.iuvya.demo.controller.CalcServiceImpl.*(..))")
public void beforeN() {
System.out.println("@Before前置通知");
}
@After("execution(public int com.iuvya.demo.controller.CalcServiceImpl.*(..))")
public void afterN() {
System.out.println("@After后置通知");
}
@AfterReturning("execution(public int com.iuvya.demo.controller.CalcServiceImpl.*(..))")
public void afterReturningN() {
System.out.println("@AfterReturning返回后通知");
}
@AfterThrowing("execution(public int com.iuvya.demo.controller.CalcServiceImpl.*(..))")
public void afterThrowingN() {
System.out.println("@AfterThrowing异常通知");
}
@Around("execution(public int com.iuvya.demo.controller.CalcServiceImpl.*(..))")
public Object around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
Object retVal = null;
System.out.println("@Around 环绕通知前");
proceedingJoinPoint.proceed();
System.out.println("@Around 环绕通知后");
return retVal;
}
}
Spring版本为5.2.7.RELEASE之前:
正常情况:
@Around 环绕通知前
@Before前置通知
result:5
@Around 环绕通知后
@After后置通知
@AfterReturning返回后通知
异常情况:
@Around 环绕通知前
@Before前置通知
@After后置通知
@AfterThrowing异常通知
Spring版本为5.2.7.RELEASE之后:
正常情况:
@Around 环绕通知前
@Before前置通知
result:5
@AfterReturning返回后通知
@After后置通知
@Around 环绕通知后
异常情况:
@Around 环绕通知前
@Before前置通知
@AfterThrowing异常通知
@After后置通知