@AspectJ使用批注重写接口方法的方法的切入点

2022-09-02 10:32:47

如何编写适用于使用注释覆盖接口方法的方法执行的 aspectj 切点?例如:

interface A {
  @MyAnnotation void method();
}
class B implements A {
  void method();
}

仅当带有注释本身时,切入点才会匹配。有没有另一种方法可以做到这一点?execution(@MyAnnotation * *.*(..))B.method()


答案 1

正如Nicholas所指出的,这在AspectJ中是不可能的。以下是为什么这是不可能的更多证据(摘自 http://www.eclipse.org/aspectj/doc/released/adk15notebook/annotations-pointcuts-and-advice.html 部分 注释继承和切入点匹配):

根据 Java 5 规范,非类型注释不会被继承,并且只有当类型具有元注释@Inherited时,才会继承对类型的注释。对 c2.aMethod(在示例中为 b.method())的调用不匹配,因为修饰符(可见性修饰符、批注和抛出子句)的连接点匹配基于连接点的主题(实际调用的方法)。

在遇到同样的问题之后,我写了一个小方法/库,可以让你为这些方法编写切入点。以下是它如何适用于您的示例:

myAnnotationIsExecuted(): execution(public * *.*(..)) && 
             if(implementsAnnotation("@MyAnnotation()", thisJoinPoint));

myAnnotationIsExecuted(): execution(public * A+.*(..)) &&
             if(implementsAnnotation("@MyAnnotation()", thisJoinPoint));

该方法来自库;检查实现的方法是否包含指定批注的基本方法。implementsAnnotation(String,JoinPoint)

有关方法/库的更多信息,请点击此处。


答案 2

更新

由于它似乎无法在Spring中完成(请参阅原始答案),我会说您需要在实现类上的每个方法中添加注释。有一个明显的方法可以做到这一点,但我想如果你正在寻找一种更自动的方法,你需要自己写一个。

我可以想象某种自产的后处理器,它将寻找特定的注释,比如说。找到此注释后,它将扫描源代码以继承成员,并在编译发生之前根据需要添加请求的注释。@ApplyThisAnnotationToAllWhoInheritMe

无论如何,如果您使用Spring AOP来执行此操作,则似乎它需要在实现者方法上。如果你希望这能有所帮助的类超出了你的控制范围,你可能不得不编写自己的Spring AOP工具。

原始答案

来自 Spring 3.0 文档

AspectJ遵循Java的规则,即接口上的注释不会被继承。

我在 章节中发现了这一点,这是 的一部分,这让我认为这是一个全局规则。7.8.2 Other Spring aspects for AspectJ7.8 Using AspectJ with Spring applications


推荐