Spring AOP中Aspect方法执行顺序

    首先先贴个总结比较好的一个博客:Spring AOP @Before @Around @After 等 advice 的执行顺序。但是其中有个错误,异常情况下,method执行完会直接执行@After 方法,而不会再执行@Around 后面的代码。所以,其中的图是有问题的。

1.单个方法被单个Aspect拦截

1.1 正常情况:

public interface Person {
    String sayHello(String name);

    void eat(String food);
}
@Component
public class Chinese implements Person {
    @Timer
    @Override
    public String sayHello(String name) {
        System.out.println("-- sayHello() --");
        return name + " hello, AOP";
    }

    @Override
    public void eat(String food) {
        System.out.println("我正在吃:" + food);
//        sayHello("hello");
    }
}
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Timer {
}
@SpringBootApplication
@RestController
public class SpringBootDemoApplication {

    //这里必须使用Person接口做注入
    @Autowired
    private Person chinese;

    @RequestMapping("/test")
    public void test() {
        chinese.sayHello("listen");
        System.out.println(chinese.getClass());
    }

    public static void main(String[] args) {
        SpringApplication.run(SpringBootDemoApplication.class, args);
    }
}
@Aspect
@Component
public class AdviceTest {
    @Pointcut("@annotation(com.haocdp.coding.spring.Timer)")
    public void pointcut() {
    }

    @Before("pointcut()")
    public void before() {
        System.out.println("before");
    }

    @After("pointcut()")
    public void after() {
        System.out.println("after");
    }

    @AfterReturning(pointcut = "pointcut()")
    public void afterReturning() {
        System.out.println("after return");
    }

    @AfterThrowing(pointcut = "pointcut()")
    public void afterThrowing() {
        System.out.println("after throwing");
    }

    @Around("pointcut()")
    public void around(ProceedingJoinPoint pjp) throws Throwable {
        System.out.println("before around");
        pjp.proceed();
        System.out.println("after around");
    }
}

执行结果:

before around
before
-- sayHello() --
after around
after
after return

1.2 异常情况:

修改Chinese代码:

@Component
public class Chinese implements Person {
    @Timer
    @Override
    public String sayHello(String name) {
        throw new IllegalArgumentException("异常");
    }

    @Override
    public void eat(String food) {
        System.out.println("我正在吃:" + food);
//        sayHello("hello");
    }
}
执行结果:
before around
before
抛出异常
after
after throwing

2.单个方法被多个Aspect拦截

新加Aspect类:

@Aspect
@Component
public class AdviceTest2 {
    @Pointcut("@annotation(com.haocdp.coding.spring.Timer)")
    public void pointcut() {
    }

    @Before("pointcut()")
    public void before() {
        System.out.println("before-2");
    }

    @After("pointcut()")
    public void after() {
        System.out.println("after-2");
    }

    @AfterReturning(pointcut = "pointcut()")
    public void afterReturning() {
        System.out.println("after return -2");
    }

    @AfterThrowing(pointcut = "pointcut()")
    public void afterThrowing() {
        System.out.println("after throwing -2");
    }

    @Around("pointcut()")
    public void around(ProceedingJoinPoint pjp) throws Throwable {
        System.out.println("before around -2");
        pjp.proceed();
        System.out.println("after around -2");
    }
}

执行结果:

情况1:

before around -2
before-2
before around
before
-- sayHello() --
after around
after
after return
after around -2
after-2
after return -2 

情况2:

before around
before
before around -2
before-2
-- sayHello() --
after around -2
after-2
after return -2
after around
after
after return

哪个Aspect先执行是随机的,如果需要定义顺序,可以使用@Order注解修饰Aspect类。值越小,优先级越高。

@Order(1)
@Aspect
@Component
public class AdviceTest2 {
    @Pointcut("@annotation(com.haocdp.coding.spring.Timer)")
    public void pointcut() {
    }

    @Before("pointcut()")
    public void before() {
        System.out.println("before-2");
    }

    @After("pointcut()")
    public void after() {
        System.out.println("after-2");
    }

    @AfterReturning(pointcut = "pointcut()")
    public void afterReturning() {
        System.out.println("after return -2");
    }

    @AfterThrowing(pointcut = "pointcut()")
    public void afterThrowing() {
        System.out.println("after throwing -2");
    }

    @Around("pointcut()")
    public void around(ProceedingJoinPoint pjp) throws Throwable {
        System.out.println("before around -2");
        pjp.proceed();
        System.out.println("after around -2");
    }
}
@Order(2)
@Aspect
@Component
public class AdviceTest {
    @Pointcut("@annotation(com.haocdp.coding.spring.Timer)")
    public void pointcut() {
    }

    @Before("pointcut()")
    public void before() {
        System.out.println("before");
    }

    @After("pointcut()")
    public void after() {
        System.out.println("after");
    }

    @AfterReturning(pointcut = "pointcut()")
    public void afterReturning() {
        System.out.println("after return");
    }

    @AfterThrowing(pointcut = "pointcut()")
    public void afterThrowing() {
        System.out.println("after throwing");
    }

    @Around("pointcut()")
    public void around(ProceedingJoinPoint pjp) throws Throwable {
        System.out.println("before around");
        pjp.proceed();
        System.out.println("after around");
    }
}

这样的执行结果就一直会是:

before around -2
before-2
before around
before
-- sayHello() --
after around
after
after return
after around -2
after-2
after return -2 




你可能感兴趣的:(Java,Spring)