如何确保java中的注释执行顺序?

我有2个自定义注释,但一个应该总是在另一个之前执行。 我如何确保这一点? 是否有某种排序或使用附加的方法定义进行排序?


您可以使用@Order批注确保您的自定义批注的顺序。

https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/core/annotation/Order.html

例:

第一个注释:

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface CustomAnnotation {
}

@Aspect
@Component
@Order(value = 1)
public class CustomAnnotationInterceptor {

    @Before("@annotation(customAnnotation )")
    public void intercept(JoinPoint method, CustomAnnotation customAnnotation ) {
        //Code here
    }
}

第二个注释:

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface CustomAnnotationTwo {
}

@Aspect
@Component
@Order(value = 2)
public class CustomAnnotationInterceptorTwo {

    @Before("@annotation(customAnnotationTwo )")
    public void intercept(JoinPoint method, CustomAnnotationTwo customAnnotationTwo ) {
        //Code here
    }

使用它们:

@CustomAnnotationTwo
@CustomAnnotation
public void someMethod(){
}

在这个例子中,CustomAnnotationInterceptor将首先执行。


我知道这是一个非常古老的问题,但我只是想记录我的发现。 任何人都可以确认这些是否正确? 在这个页面中已经提到Spring文档说除非使用@Order注解,否则注释的执行是未定义的。 我尝试重新命名Aspect类并进行了多次测试,发现Aspect类按字母顺序执行,发现结果是一致的。

以下是我的示例代码:

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface A {}

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface B {}

@Aspect
public class A_Aspect {

@Around("@annotation(mypackage.A)")
public void around(ProceedingJoinPoint joinPoint) {
    System.out.println("A_Aspect");
    joinPoint.proceed();
    }
}

@Aspect
public class B_Aspect {

    @Around("@annotation(mypackage.B)")
    public void around(ProceedingJoinPoint joinPoint) {
        System.out.println("B_Aspect");
        joinPoint.proceed();
    }
}

class AdvisedClass{
    @B
    @A
    public void advisedMethod(){}
}

当我尝试执行adviceMethod()时,以下是我收到的日志:

A_Aspect
B_Aspect

我更改了注释声明序列:

@A
@B  
public void advisedMethod(){}

以下是日志:

A_Aspect
B_Aspect

我将Annotation @A重命名为@C,以下是日志:

A_Aspect
B_Aspect

但是,当我尝试将Aspect class A_Aspect重命名为C_Aspect时,以下是日志:

B_Aspect
C_Aspect

正如我所说,我希望有人确认这一点,因为我找不到任何文件


从http://static.springsource.org/spring/docs/3.2.x/spring-framework-reference/html/aop.html#aop-ataspectj-advice-ordering

Spring AOP遵循与AspectJ相同的优先规则来确定建议执行的顺序。 最高优先级建议首先“在途中”运行(因此给定两条先前的建议,最高优先级的建议先运行)。 从连接点出来的“出路”中,最高优先级通知最后运行(因此给定两条通知后,优先级最高的通道将运行第二条通道)。

当在不同方面定义的两条建议都需要在同一个连接点上运行时,除非您另行指定,否则执行顺序未定义。 您可以通过指定优先级来控制执行顺序。 这是以普通的Spring方式完成的,方法是在aspect类中实现org.springframework.core.Ordered接口或使用Order注释对其进行注释。 给定两个方面,从Ordered.getValue()(或注释值)返回较低值的方面具有较高的优先级。

当在同一方面定义的两条建议都需要在同一个连接点上运行时,排序是未定义的(因为无法通过javac编译类的反射检索声明顺序)。 考虑将这些通知方法分解为每个方面类中每个连接点的一个通知方法,或者将通知重构为单独的方面类 - 可以在方面级别进行排序。

链接地址: http://www.djcxy.com/p/11701.html

上一篇: How to ensure annotations execution order in java?

下一篇: Many warnings while deploy glassfish v3