如何让 Spring 方面支持可重复注释?
How to have Spring aspect support for repeatable annotation?
我已经创建了一个 java 17 可重复注释,并且想要创建一个方面 围绕 调用包含该注释的方法。当方法被注释一次但在我有可重复的注释时无法调用时,这似乎有效。我正在使用 aspectjrt 版本 1.9.7。我做错了什么或方面不支持可重复的注释吗?有相同的解决方法吗?
注释class ->
@Repeatable(Schedules.class)
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Schedule {
String dayOfMonth() default "first";
String dayOfWeek() default "Mon";
int hour() default 12;
}
可重复的class ->
@Retention(value = RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Schedules {
Schedule[] value();
}
看点class ->
@Aspect
@Component
@Slf4j
public class Aspect {
@Around("@annotation(Schedule)")
public Object trace(ProceedingJoinPoint joinPoint) throws Throwable {
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
Method method = signature.getMethod();
Schedule filters = method.getAnnotation(Schedule.class);
//Business Logic
return joinPoint.proceed();
}
}
这实际上不是 AOP 问题,但您需要了解可重复注释在 Java 中的工作原理:如果注释在被注释的元素上出现多次,则不再表示为单个注释,而是作为 @Repeatable
中提到的注释类型的 value()
中的注释数组,即在您的情况下 @Schedules
(复数“s”!)。
就您而言,这意味着您需要两个切入点,一个用于 single-annotation 情况,一个用于 multi-annotation 情况。我建议将常见的建议代码分解为方面的辅助方法,该方法始终采用可重复注释的数组,然后在一种情况下仅传递包装器注释的值,在一种情况下传递 one-element 数组其他情况。
如果有任何不清楚的地方,请随时提出 follow-up 问题。但它应该是直截了当的,几乎是微不足道的。
资源:
- https://docs.oracle.com/javase/tutorial/java/annotations/repeating.html
- https://dzone.com/articles/repeatable-annotations-in-java-8-1
P.S.: 你应该了解如何将注释绑定到通知方法参数:
@Around("@annotation(schedule)")
public Object traceSingle(ProceedingJoinPoint joinPoint, Schedule schedule) throws Throwable
// ...
@Around("@annotation(schedules)")
public Object traceMultiple(ProceedingJoinPoint joinPoint, Schedules schedules) throws Throwable
我已经创建了一个 java 17 可重复注释,并且想要创建一个方面 围绕 调用包含该注释的方法。当方法被注释一次但在我有可重复的注释时无法调用时,这似乎有效。我正在使用 aspectjrt 版本 1.9.7。我做错了什么或方面不支持可重复的注释吗?有相同的解决方法吗?
注释class ->
@Repeatable(Schedules.class)
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Schedule {
String dayOfMonth() default "first";
String dayOfWeek() default "Mon";
int hour() default 12;
}
可重复的class ->
@Retention(value = RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Schedules {
Schedule[] value();
}
看点class ->
@Aspect
@Component
@Slf4j
public class Aspect {
@Around("@annotation(Schedule)")
public Object trace(ProceedingJoinPoint joinPoint) throws Throwable {
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
Method method = signature.getMethod();
Schedule filters = method.getAnnotation(Schedule.class);
//Business Logic
return joinPoint.proceed();
}
}
这实际上不是 AOP 问题,但您需要了解可重复注释在 Java 中的工作原理:如果注释在被注释的元素上出现多次,则不再表示为单个注释,而是作为 @Repeatable
中提到的注释类型的 value()
中的注释数组,即在您的情况下 @Schedules
(复数“s”!)。
就您而言,这意味着您需要两个切入点,一个用于 single-annotation 情况,一个用于 multi-annotation 情况。我建议将常见的建议代码分解为方面的辅助方法,该方法始终采用可重复注释的数组,然后在一种情况下仅传递包装器注释的值,在一种情况下传递 one-element 数组其他情况。
如果有任何不清楚的地方,请随时提出 follow-up 问题。但它应该是直截了当的,几乎是微不足道的。
资源:
- https://docs.oracle.com/javase/tutorial/java/annotations/repeating.html
- https://dzone.com/articles/repeatable-annotations-in-java-8-1
P.S.: 你应该了解如何将注释绑定到通知方法参数:
@Around("@annotation(schedule)")
public Object traceSingle(ProceedingJoinPoint joinPoint, Schedule schedule) throws Throwable
// ...
@Around("@annotation(schedules)")
public Object traceMultiple(ProceedingJoinPoint joinPoint, Schedules schedules) throws Throwable