Spring AMP 以相反的顺序运行
Spring AOP runs in reveres order
我目前遇到了一些很奇怪的事情。我必须看点 类,它们在 AfterThrowing 标记中都有相同的切入点。
方面 类 是有序的,但优先级较低的总是先运行,我认为这与预期行为相反。
@Configuration
@EnableAspectJAutoProxy(proxyTargetClass = true)
@Aspect
@Order(1)
public class AspectOne {
@AfterThrowing(pointcut = "exection(* com.test.*..*(..))", throwing = "ex")
public void doSomething(JoinPoint jp, Exception ex){
System.out.println("AspectOne");
}
@Configuration
@EnableAspectJAutoProxy(proxyTargetClass = true)
@Aspect
@Order(2)
public class AspectTwo {
@AfterThrowing(pointcut = "exection(* com.test.*..*(..))", throwing = "ex")
public void doSomething(JoinPoint jp, Exception ex){
System.out.println("AspectTwo");
}
根据文档,数字越小,出现率越高。
然而我的输出是:
- AspectTwo
- AspectOne
如果我调换顺序,结果也会改变。所以 The Order 正在运作,但它应该以相反的方式运作。我尝试了不同的数字,结果是一样的。
订单在这方面有效,并且按预期工作。然而,after advices 以 reverse 顺序执行。
想象一下您的相位同时具有 @Before
和 @After
@Component
@Aspect
@Order(1)
public class AspectOne {
@Before(pointcut = "exection(* com.test.*..*(..))")
public void soSomethingBefore(Joinpoint jp) {
System.out.println("[BEFORE] AspectOne");
}
@AfterThrowing(pointcut = "exection(* com.test.*..*(..))", throwing = "ex")
public void doSomething(JoinPoint jp, Exception ex){
System.out.println("[AFTER ] AspectOne");
}
和
@Component
@Aspect
@Order(2)
public class AspectTwo {
@Before(pointcut = "exection(* com.test.*..*(..))")
public void soSomethingBefore(Joinpoint jp) {
System.out.println("[BEFORE] AspectTwo");
}
@AfterThrowing(pointcut = "exection(* com.test.*..*(..))", throwing = "ex")
public void doSomething(JoinPoint jp, Exception ex){
System.out.println("[AFTER ] AspectTwo");
}
如果您要查看输出,它将是
[BEFORE] AspectOne
[BEFORE] AspectTwo
[AFTER ] AspectTwo
[AFTER ] AspeectOne
所以排序是有规律的,但是你必须考虑到建议的顺序是相反的。
您可能想知道为什么?
让我们接受一个 @Around
的建议,它基本上是一个 @Before
和一个 @After
的建议。如果第一个方面是关于开始交易,它应该是 last 到 commit/rollback 交易,因为介于两者之间的所有内容都应该参与同一交易。如果它是第一个开始并提交执行的其他部分,则不会成为 tx 的一部分,可能会导致奇怪的问题。
注意: 请删除 @Configuration
和 @EnableAspectJAutoProxy
只需创建 1 个配置 class 来执行此操作,并使您的方面正常 @Component
classes.
我目前遇到了一些很奇怪的事情。我必须看点 类,它们在 AfterThrowing 标记中都有相同的切入点。 方面 类 是有序的,但优先级较低的总是先运行,我认为这与预期行为相反。
@Configuration
@EnableAspectJAutoProxy(proxyTargetClass = true)
@Aspect
@Order(1)
public class AspectOne {
@AfterThrowing(pointcut = "exection(* com.test.*..*(..))", throwing = "ex")
public void doSomething(JoinPoint jp, Exception ex){
System.out.println("AspectOne");
}
@Configuration
@EnableAspectJAutoProxy(proxyTargetClass = true)
@Aspect
@Order(2)
public class AspectTwo {
@AfterThrowing(pointcut = "exection(* com.test.*..*(..))", throwing = "ex")
public void doSomething(JoinPoint jp, Exception ex){
System.out.println("AspectTwo");
}
根据文档,数字越小,出现率越高。 然而我的输出是:
- AspectTwo
- AspectOne
如果我调换顺序,结果也会改变。所以 The Order 正在运作,但它应该以相反的方式运作。我尝试了不同的数字,结果是一样的。
订单在这方面有效,并且按预期工作。然而,after advices 以 reverse 顺序执行。
想象一下您的相位同时具有 @Before
和 @After
@Component
@Aspect
@Order(1)
public class AspectOne {
@Before(pointcut = "exection(* com.test.*..*(..))")
public void soSomethingBefore(Joinpoint jp) {
System.out.println("[BEFORE] AspectOne");
}
@AfterThrowing(pointcut = "exection(* com.test.*..*(..))", throwing = "ex")
public void doSomething(JoinPoint jp, Exception ex){
System.out.println("[AFTER ] AspectOne");
}
和
@Component
@Aspect
@Order(2)
public class AspectTwo {
@Before(pointcut = "exection(* com.test.*..*(..))")
public void soSomethingBefore(Joinpoint jp) {
System.out.println("[BEFORE] AspectTwo");
}
@AfterThrowing(pointcut = "exection(* com.test.*..*(..))", throwing = "ex")
public void doSomething(JoinPoint jp, Exception ex){
System.out.println("[AFTER ] AspectTwo");
}
如果您要查看输出,它将是
[BEFORE] AspectOne
[BEFORE] AspectTwo
[AFTER ] AspectTwo
[AFTER ] AspeectOne
所以排序是有规律的,但是你必须考虑到建议的顺序是相反的。
您可能想知道为什么?
让我们接受一个 @Around
的建议,它基本上是一个 @Before
和一个 @After
的建议。如果第一个方面是关于开始交易,它应该是 last 到 commit/rollback 交易,因为介于两者之间的所有内容都应该参与同一交易。如果它是第一个开始并提交执行的其他部分,则不会成为 tx 的一部分,可能会导致奇怪的问题。
注意: 请删除 @Configuration
和 @EnableAspectJAutoProxy
只需创建 1 个配置 class 来执行此操作,并使您的方面正常 @Component
classes.