@Aspect@Componentpublic class TulingAspect {@Before("execution(public void com.tuling.service.AService.test())")public void tulingBefore() {System.out.println("lubanBefore");}@Before("execution(public void com.tuling.service.AService.test())")public void tulingBefore1111() {System.out.println("lubanBefore1111");}}
定义了两个@Before,对应同一个切点,那么在执行时,到底哪个@Before会先执行?答案是:
tulingBefore
tulingBefore1111
那么难道是按方法定义顺序来执行的?并不是,在Spring的源码中存在一个步骤叫做解析Advisor,对应的代码为
这个方法会遍历aspect类的所有方法,如果方法上没有@Pointcut则把该方法加入methods集合,然后利用一个叫做METHOD_COMPARATOR的比较器进行排序。
METHOD_COMPARATOR对应的代码如下:
adviceKindComparator表示按方法上的注解进行排序,对于相同的注解则按methodNameComparator进行比较排序。
ConvertingComparator中的compare方法为:
影响排序的就是这个converter,converter就是外头传进来的Method::getName,所以就是获取方法名字,然后比较方法名字。
所以,我们可以得出结论,两个@Before最终是按方法名字进行排序的。如果我们把测试代码改成:
@Aspect@Componentpublic class TulingAspect {@Before("execution(public void com.tuling.service.AService.test())")public void tulingBefore() {System.out.println("tulingBefore");}@Before("execution(public void com.tuling.service.AService.test())")public void atulingBefore1111() {System.out.println("atulingBefore1111");}}
那么按源码分析来说,atulingBefore1111就应该先执行了,最后测试通过。
