Spring AOP:切面优先级

Advice ordering

What happens when multiple pieces of advice all want to run at the same join point? 
Spring AOP follows the same precedence rules as AspectJ to determine the order of 
advice execution. The highest precedence advice runs first "on the way in" (so 
given two pieces of before advice, the one with highest precedence runs first). "On 
the way out" from a join point, the highest precedence advice runs last (so given 
two pieces of after advice, the one with the highest precedence will run second).

When two pieces of advice defined in different aspects both need to run at the same
 join point, unless you specify otherwise the order of execution is undefined. You 
can control the order of execution by specifying precedence. This is done in the 
normal Spring way by either implementing the org.springframework.core.Ordered 
interface in the aspect class or annotating it with the Order annotation. Given two 
aspects, the aspect returning the lower value from Ordered.getValue() (or the 
annotation value) has the higher precedence.

When two pieces of advice defined in the same aspect both need to run at the same
 join point, the ordering is undefined (since there is no way to retrieve the 
declaration order via reflection for javac-compiled classes). Consider collapsing 
such advice methods into one advice method per join point in each aspect class, or
 refactor the pieces of advice into separate aspect classes - which can be ordered 
at the aspect level.

简译如下:

如果在同一接入点(join point) 有多个增强(advice),Spring AOP 采用和 AspectJ 类似的优先级来指定通知的执行顺序。目标执行前(进入时),优先级高的通知执行,目标执行后(出来时),优先级高的通知执行。

  1. 如果两个通知分别定义在各自的 Aspect 内,可以通过如下两种方式控制 Aspect 的施加顺序:

    • Aspect 类添加注解:org.springframework.core.annotation.Order
      • 顺序值:使用注解属性指定
    • Aspect 类实现接口:org.springframework.core.Ordered
      • 顺序值:实现 Ordered 接口的 getOrder() 方法即可
  2. 如果两个 advice 位于同一 aspect 内,且执行顺序有先后,通过 advice 的声明顺序是无法确定其执行顺序的(advice 方法的声明顺序无法通过反射获取)而且@Order此处也无效,只能采取如下变通方式,二选一:

    1. 将两个 advice 合并为一个 advice,那么执行顺序就可以通过代码控制了
    2. 将两个 advice 分别抽离到各自的 aspect 内,然后为 aspect 指定执行顺序
  3. 不同种 advice的执行顺序:
    这里写图片描述

补充:

  • Spring 的声明式事务同样基于 Spring AOP,其中事务切面(Transactional Aspect)的优先级(priority)最低。
  • advice method 的优先级调用,与普通方法的调用过程一致,实质上都是栈帧压栈出栈的过程,高优先级先进后出,低优先级后进先出 。

猜你喜欢

转载自blog.csdn.net/qq_32331073/article/details/80596084
今日推荐