AOP注解的执行顺序

133 阅读2分钟

1、结论

@Around@Before → 方法执行 → @AfterReturning/Throwing@After@Around

2、执行过程

github.com/wangzhan666…

测试demo

切面A:

@Aspect
@Component
@Order(1) // 最高优先级
public class AspectA {

    @Before("execution(* com.wangzhan.service.DemoService.*(..))")
    public void beforeAdvice() {
        System.out.println("[AspectA] @Before 执行");
    }

    @Around("execution(* com.wangzhan.service.DemoService.*(..))")
    public Object aroundAdvice(ProceedingJoinPoint joinPoint) throws Throwable {
        System.out.println("[AspectA] @Around 开始");
        try {
            Object result = joinPoint.proceed();
            System.out.println("[AspectA] @Around 正常结束");
            return result;
        } catch (Exception e) {
            System.out.println("[AspectA] @Around 捕获异常: " + e.getMessage());
            throw e;
        }
    }

    @After("execution(* com.wangzhan.service.DemoService.*(..))")
    public void afterAdvice() {
        System.out.println("[AspectA] @After 执行");
    }

    @AfterReturning(pointcut = "execution(* com.wangzhan.service.DemoService.*(..))", returning = "result")
    public void afterReturningAdvice(Object result) {
        System.out.println("[AspectA] @AfterReturning 执行: " + result);
    }

    @AfterThrowing(pointcut = "execution(* com.wangzhan.service.DemoService.*(..))", throwing = "ex")
    public void afterThrowingAdvice(Exception ex) {
        System.out.println("[AspectA] @AfterThrowing 执行: " + ex.getMessage());
    }
}

切面B:

@Aspect
@Component
@Order(2) // 次高优先级
public class AspectB {

    @Before("execution(* com.wangzhan.service.DemoService.*(..))")
    public void beforeAdvice() {
        System.out.println("[AspectB] @Before 执行");
    }

    @Around("execution(* com.wangzhan.service.DemoService.*(..))")
    public Object aroundAdvice(ProceedingJoinPoint joinPoint) throws Throwable {
        System.out.println("[AspectB] @Around 开始");
        try {
            Object result = joinPoint.proceed();
            System.out.println("[AspectB] @Around 正常结束");
            return result;
        } catch (Exception e) {
            System.out.println("[AspectB] @Around 捕获异常: " + e.getMessage());
            throw e;
        }
    }

    @After("execution(* com.wangzhan.service.DemoService.*(..))")
    public void afterAdvice() {
        System.out.println("[AspectB] @After 执行");
    }

    @AfterReturning(pointcut = "execution(* com.wangzhan.service.DemoService.*(..))", returning = "result")
    public void afterReturningAdvice(Object result) {
        System.out.println("[AspectB] @AfterReturning 执行: " + result);
    }

    @AfterThrowing(pointcut = "execution(* com.wangzhan.service.DemoService.*(..))", throwing = "ex")
    public void afterThrowingAdvice(Exception ex) {
        System.out.println("[AspectB] @AfterThrowing 执行: " + ex.getMessage());
    }
}

service层:

@Service
public class DemoService {

    public String doSomething(String input) {
        System.out.println("==> 执行目标方法: " + input);
        return "处理后的: " + input;
    }

    public String throwException() throws Exception {
        System.out.println("==> 执行会抛出异常的方法");
        throw new Exception("测试异常");
    }
}

controller层:

@RestController
public class DemoController {

    @Autowired
    private DemoService demoService;

    @GetMapping("/test")
    public String test(@RequestParam String input) {
        return demoService.doSomething(input);
    }

    @GetMapping("/test-exception")
    public String testException() throws Exception {
        return demoService.throwException();
    }
}

启动类:

@SpringBootApplication
@EnableAspectJAutoProxy
public class AopDemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(AopDemoApplication.class, args);
    }

}

访问正常执行过程:http://localhost:8888/test?input=hello

[AspectA] @Around 开始
[AspectA] @Before 执行
[AspectB] @Around 开始
[AspectB] @Before 执行
==> 执行目标方法: hello
[AspectB] @AfterReturning 执行: 处理后的: hello
[AspectB] @After 执行
[AspectB] @Around 正常结束
[AspectA] @AfterReturning 执行: 处理后的: hello
[AspectA] @After 执行
[AspectA] @Around 正常结束

访问异常执行过程:http://localhost:8888/test-exception?input=hello

[AspectA] @Around 开始
[AspectA] @Before 执行
[AspectB] @Around 开始
[AspectB] @Before 执行
==> 执行会抛出异常的方法
[AspectB] @AfterThrowing 执行: 测试异常
[AspectB] @After 执行
[AspectB] @Around 捕获异常: 测试异常
[AspectA] @AfterThrowing 执行: 测试异常
[AspectA] @After 执行
[AspectA] @Around 捕获异常: 测试异常