如何编写适用于方法执行的 aspectj 切入点,该方法执行使用注释覆盖接口方法?例如:
interface A {
@MyAnnotation void method();
}
class B implements A {
void method();
}
切入点仅在带有注释本身execution(@MyAnnotation * *.*(..))
时才匹配。B.method()
还有另一种方法可以做到这一点吗?
正如 Nicholas 指出的,这在 AspectJ 中是不可能的。这是为什么不可能的更多证据(取自http://www.eclipse.org/aspectj/doc/released/adk15notebook/annotations-pointcuts-and-advice.html部分注释继承和切入点匹配):
根据 Java 5 规范,非类型注解不会被继承,而类型上的注解只有在具有 @Inherited 元注解时才会被继承。对 c2.aMethod 的调用(在您的示例中为 b.method() )不匹配,因为修饰符(可见性修饰符、注释和 throws 子句)的连接点匹配基于连接点的主题(方法实际被调用)。
在遇到同样的问题后,我编写了一个小方法/库,允许您为此类方法编写切入点。以下是它对您的示例的工作方式:
myAnnotationIsExecuted(): execution(public * *.*(..)) &&
if(implementsAnnotation("@MyAnnotation()", thisJoinPoint));
或者
myAnnotationIsExecuted(): execution(public * A+.*(..)) &&
if(implementsAnnotation("@MyAnnotation()", thisJoinPoint));
该方法implementsAnnotation(String,JoinPoint)
来自图书馆;检查实现的方法是否包含指定注释的基本方法。
有关方法/库的更多信息可以在这里找到。
更新
由于它似乎无法在 Spring 中完成(请参阅原始答案),我会说您需要将注释添加到实现类的每个方法中。有一种明显的方法可以做到这一点,但我想如果你正在寻找一种更自动化的方法,你需要自己编写一个。
我可以想象某种本土的后处理器会寻找特定的注释,比如说@ApplyThisAnnotationToAllWhoInheritMe
. 一旦找到此注解,它将扫描源代码以查找继承成员,并在编译发生之前在必要的地方添加请求的注解。
无论如何,如果您使用 Spring AOP 来执行此操作,它似乎需要在 implementationers 方法上。如果您希望这会有所帮助的类超出您的控制范围,您可能必须编写自己的 Spring AOP 工具。
原始答案
AspectJ 遵循 Java 的规则,即不继承接口上的注释。
我在 section 中找到了这一点7.8.2 Other Spring aspects for AspectJ
,它是 的一部分7.8 Using AspectJ with Spring applications
,这让我认为这是一个全局规则。
//introducing empty marker interface
declare parents : hasmethod(@MyAnnotation * *(..)) implements TrackedParentMarker;
public pointcut p1() : execution(* TrackedParentMarker+.*(..));
您还应该启用 –XhasMember 编译器标志。