Spring 'nested' 注释的 AOP 切点
Spring AOP point cut for 'nested' annotation
我需要定义一个切点,它会触发对使用自定义注释进行注释的 spring 服务的所有方法的执行。我想定义切点的注释将在另一个注释上。
@Y
public @interface X {
}
然后该服务将被注释如下
@X
public Service1 {
}
我尝试使用以下切点定义,但它仅在@Y 在服务本身上时有效,这意味着它看不到注释在@X 上
@Around("@within(com.mypackage.Y)")
这不是 Spring 或 AspectJ 问题。在 Java 中,接口上的注释、其他注释或方法永远不会通过使用带注释的注释或重写方法实现 类、类 来继承。注解继承仅适用于从 类 到子 类,但前提是超类中使用的注解类型带有元注解 @Inherited
.
更新: 因为我之前已经多次回答过这个问题,所以我刚刚在 .
中记录了这个问题和解决方法
这里有一点证明你想要的东西不起作用,因此也不能被一个方面利用:
package de.scrum_master.app;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@Inherited
@Retention(RetentionPolicy.RUNTIME)
public @interface OuterAnnotation {}
package de.scrum_master.app;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@Inherited
@Retention(RetentionPolicy.RUNTIME)
@OuterAnnotation
public @interface InnerAnnotation {}
package de.scrum_master.app;
import java.lang.annotation.Annotation;
@InnerAnnotation
public class Application {
public static void main(String[] args) {
for (Annotation annotation : Application.class.getAnnotations())
System.out.println(annotation);
}
}
控制台输出显示 JVM 只能看到内部注释,而不是内部注释上使用的外部注释:
@de.scrum_master.app.InnerAnnotation()
更新: 对 Bradley M Handy 的回答很感兴趣,我重新检查了它是否也适用于我的代码中描述的情况,确实如此。这种类型的 AspectJ 语法对我来说是未知的,尽管我认为我对 AspectJ 了解很多。所以谢谢,布拉德利。 :-) 这方面会起作用:
package de.scrum_master.aspect;
import de.scrum_master.app.OuterAnnotation;
public aspect MetaAnnotationAspect {
after() : within(@(@OuterAnnotation *) *) && execution(* *(..)) {
System.out.println(thisJoinPoint);
}
}
运行 应用程序时的控制台日志:
@de.scrum_master.app.InnerAnnotation()
execution(void de.scrum_master.app.Application.main(String[]))
我在应用程序中有这个确切的需求。我找到了这个答案,但对无法完成感到不满意。
经过更多搜索,我找到了这个 cheat sheet for AspectJ/Spring 切入点表达式。作弊 sheet 中的解决方案并没有像宣传的那样完全有效,但我能够让它为我所需要的工作。
@Pointcut("within(@(@Annotation *) *)")
public void classAnnotatedWithNestedAnnotationOneLevelDeep() { }
我将此表达式与 @within
表达式组合,仅 @Annotation
得到我想要的结果。
对于方法执行:
@Pointcut("execution(@(@com.someorg.SomeAnnotation *) * *(..))")
public void methodAnnotatedWithNestedAnnotationOneLevelDeep() { }
我将此表达式与 @annotation
表达式结合起来,仅用于 @Annotation
以获得我想要用于方法的内容。
我需要定义一个切点,它会触发对使用自定义注释进行注释的 spring 服务的所有方法的执行。我想定义切点的注释将在另一个注释上。
@Y
public @interface X {
}
然后该服务将被注释如下
@X
public Service1 {
}
我尝试使用以下切点定义,但它仅在@Y 在服务本身上时有效,这意味着它看不到注释在@X 上
@Around("@within(com.mypackage.Y)")
这不是 Spring 或 AspectJ 问题。在 Java 中,接口上的注释、其他注释或方法永远不会通过使用带注释的注释或重写方法实现 类、类 来继承。注解继承仅适用于从 类 到子 类,但前提是超类中使用的注解类型带有元注解 @Inherited
.
更新: 因为我之前已经多次回答过这个问题,所以我刚刚在
这里有一点证明你想要的东西不起作用,因此也不能被一个方面利用:
package de.scrum_master.app;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@Inherited
@Retention(RetentionPolicy.RUNTIME)
public @interface OuterAnnotation {}
package de.scrum_master.app;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@Inherited
@Retention(RetentionPolicy.RUNTIME)
@OuterAnnotation
public @interface InnerAnnotation {}
package de.scrum_master.app;
import java.lang.annotation.Annotation;
@InnerAnnotation
public class Application {
public static void main(String[] args) {
for (Annotation annotation : Application.class.getAnnotations())
System.out.println(annotation);
}
}
控制台输出显示 JVM 只能看到内部注释,而不是内部注释上使用的外部注释:
@de.scrum_master.app.InnerAnnotation()
更新: 对 Bradley M Handy 的回答很感兴趣,我重新检查了它是否也适用于我的代码中描述的情况,确实如此。这种类型的 AspectJ 语法对我来说是未知的,尽管我认为我对 AspectJ 了解很多。所以谢谢,布拉德利。 :-) 这方面会起作用:
package de.scrum_master.aspect;
import de.scrum_master.app.OuterAnnotation;
public aspect MetaAnnotationAspect {
after() : within(@(@OuterAnnotation *) *) && execution(* *(..)) {
System.out.println(thisJoinPoint);
}
}
运行 应用程序时的控制台日志:
@de.scrum_master.app.InnerAnnotation()
execution(void de.scrum_master.app.Application.main(String[]))
我在应用程序中有这个确切的需求。我找到了这个答案,但对无法完成感到不满意。
经过更多搜索,我找到了这个 cheat sheet for AspectJ/Spring 切入点表达式。作弊 sheet 中的解决方案并没有像宣传的那样完全有效,但我能够让它为我所需要的工作。
@Pointcut("within(@(@Annotation *) *)")
public void classAnnotatedWithNestedAnnotationOneLevelDeep() { }
我将此表达式与 @within
表达式组合,仅 @Annotation
得到我想要的结果。
对于方法执行:
@Pointcut("execution(@(@com.someorg.SomeAnnotation *) * *(..))")
public void methodAnnotatedWithNestedAnnotationOneLevelDeep() { }
我将此表达式与 @annotation
表达式结合起来,仅用于 @Annotation
以获得我想要用于方法的内容。