1. @Aspect
    2. @Component
    3. public class TulingAspect {
    4. @Before("execution(public void com.tuling.service.AService.test())")
    5. public void tulingBefore() {
    6. System.out.println("lubanBefore");
    7. }
    8. @Before("execution(public void com.tuling.service.AService.test())")
    9. public void tulingBefore1111() {
    10. System.out.println("lubanBefore1111");
    11. }
    12. }

    定义了两个@Before,对应同一个切点,那么在执行时,到底哪个@Before会先执行?答案是:

    tulingBefore
    tulingBefore1111

    那么难道是按方法定义顺序来执行的?并不是,在Spring的源码中存在一个步骤叫做解析Advisor,对应的代码为
    image.png

    这个方法会遍历aspect类的所有方法,如果方法上没有@Pointcut则把该方法加入methods集合,然后利用一个叫做METHOD_COMPARATOR的比较器进行排序。

    METHOD_COMPARATOR对应的代码如下:
    image.png
    adviceKindComparator表示按方法上的注解进行排序,对于相同的注解则按methodNameComparator进行比较排序。

    ConvertingComparator中的compare方法为:
    image.png
    影响排序的就是这个converter,converter就是外头传进来的Method::getName,所以就是获取方法名字,然后比较方法名字。

    所以,我们可以得出结论,两个@Before最终是按方法名字进行排序的。如果我们把测试代码改成:

    1. @Aspect
    2. @Component
    3. public class TulingAspect {
    4. @Before("execution(public void com.tuling.service.AService.test())")
    5. public void tulingBefore() {
    6. System.out.println("tulingBefore");
    7. }
    8. @Before("execution(public void com.tuling.service.AService.test())")
    9. public void atulingBefore1111() {
    10. System.out.println("atulingBefore1111");
    11. }
    12. }

    那么按源码分析来说,atulingBefore1111就应该先执行了,最后测试通过。