@AspectJ切入点覆盖带有注释的接口方法的方法

时间:2011-08-24 16:13:12

标签: java aop aspectj pointcuts pointcut

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

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

切入点execution(@MyAnnotation * *.*(..))仅在B.method()带有注释本身时才匹配。还有另一种方法吗?

3 个答案:

答案 0 :(得分:11)

正如尼古拉斯指出的那样,这在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));

OR

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

方法implementsAnnotation(String,JoinPoint)来自图书馆;检查实现的方法是否包含指定注释的基本方法。

有关方法/库的更多信息,请访问here.

答案 1 :(得分:4)

更新

因为看起来它无法在Spring中完成(参见原始答案),我想说你需要在实现类的每个方法中添加注释。有一种明显的方法可以做到这一点,但我想如果你正在寻找一种更自动的方式,你需要自己写一个。

我可以想象某种本土的后处理器会寻找特定的注释,让我们说@ApplyThisAnnotationToAllWhoInheritMe。一旦找到此注释,它将扫描源代码以继承成员,并在编译发生之前在必要时添加所请求的注释。

无论如何,如果您使用Spring AOP执行此操作,它似乎需要在实现方法上。如果您希望这些课程有所帮助,那么您可能需要编写自己的Spring AOP工具。

原始答案

来自Spring 3.0 Documentation

  

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

我在7.8.2 Other Spring aspects for AspectJ部分找到了这一点,这是7.8 Using AspectJ with Spring applications的一部分,这让我觉得这是一个全球规则。

答案 2 :(得分:2)

//introducing empty marker interface
declare parents : hasmethod(@MyAnnotation * *(..)) implements TrackedParentMarker;

public pointcut p1() : execution(* TrackedParentMarker+.*(..));

此外,您应该启用-XhasMember编译器标志。