问题产生情况
下面是注解对五个通知的配置执行顺序。
下面是XML方式对五个通知的配置执行顺序。
问题剖析
Spring AOP的注解配置和XML配置的执行顺序不一样,是因为它们底层使用了不同的AOP代理方式。
- 注解配置:
当你使用基于注解的AOP时,Spring会使用AspectJ的AOP实现。AspectJ是一个独立的AOP框架,Spring集成了AspectJ的注解支持。在基于注解的AOP中,切面逻辑是通过Java注解(如
@Before
、@After
等)来声明的,这些注解直接放在切面类的方法上。由于AspectJ切面是在编译时进行织入的,切面逻辑被编织到目标对象的字节码中。因此,基于注解的AOP的切面执行顺序在运行前就已经确定了。(在基于注解的AOP中,切面执行顺序由@Order
注解来控制,当没有指定时Spring会按照切面类的类名进行排序,从字母顺序最小的切面开始执行,依次递增) -
XML配置:
当你在XML中使用
<aop:config>
来配置切面时,Spring会使用基于代理的AOP实现。对于基于代理的AOP,Spring会创建一个代理对象,该代理对象包装了原始的目标对象,并织入了切面逻辑。在运行时,当调用代理对象的方法时,切面逻辑会在方法执行前后进行织入。在XML配置中,AOP代理是通过<aop:config>
和<aop:aspect>
等标签来定义的,代理对象是通过JDK动态代理或CGLIB代理生成的。因为代理对象是在运行时动态生成的,所以XML配置中的AOP切面执行顺序在运行时才能确定。(在XML配置中,AOP切面的执行顺序是根据切面声明的顺序来决定的。)
问题解答
改变XML配置中的声明顺序
执行结果