3

这是注释:

@Target(value = ElementType.TYPE)
@Retention(value = RetentionPolicy.RUNTIME)
@Inherited
public @interface MyAnnotation {
    String name();
}

这是一个带注释的类:

@MyAnnotation(name="foo")
public class ClassA {
    public ClassA() {
        // Do something
    }
}

这是第二个带注释的类:

@MyAnnotation(name="bar")
public class ClassB {
    public ClassB(String aString) {
        // Do something
    }
}

我正在寻找一个 aspectj 切入点,该切入点正确匹配 ClassA 和 ClassB 的构造函数,而不匹配任何其他未注释的类的任何其他构造函数MyAnnotation

4

3 回答 3

6

您的切入点应如下所示:

execution((@MyAnnotation *).new(..))

如果注解在另一个包中:

execution((@de.scrum_master.aop.demo.MyAnnotation *).new(..))

或者,如果您不想完全限定软件包:

execution((@*..MyAnnotation *).new(..))

编辑:好的,有关您的问题的更多信息在评论中:

构造函数执行没有可以捕获的返回值

after() returning(Object myObject) : myJoinpoint()

这仅适用于方法。所以请使用

after(Object myObject) returning : myJoinpoint() && this(myObject)

相反,如果您出于任何目的确实需要构造的对象。

于 2012-08-29T23:01:05.973 回答
2

这是 kriegaex 的完整工作解决方案:

public aspect AnnotationTests {
  public aspect AnnotationTests {
    after(Object myObject) returning : execution((@MyAnnotation *).new(..))
        && this(myObject) {
      System.out.println("Object class name: " + myObject.getClass().getName());
    }
  }
}

@MyAnnotation(name="foo")
public class ClassA {
  public ClassA() {
    // Do something
  }

  public static void main(String[] args) {
    ClassA classA = new ClassA();
    ClassB classB = new ClassB("");
    if (classA.getClass().getName().equals(classB.getClass().getName())) {
      throw new RuntimeException("Big problems!");
    }
  }
}

@MyAnnotation(name="bar")
public class ClassB {
  private final String aString;

  public ClassB(String aString) {
    this.aString = aString;
  }
}
于 2012-08-31T04:11:00.320 回答
0

以下作品,但 kriegaex 不推荐。此处作为可能的材料提供,如果需要,可以重新利用。

这是我对部分使用initialization()切入点原语的问题的第一个可行解决方案。

public aspect AnnotationTests {
  private pointcut genericConstructor(): initialization(*.new(..));
  private pointcut withinMyAnnotation(): @within(MyAnnotation);
  private pointcut constructorInAnnotatedClass(): genericConstructor()
      && withinMyAnnotation();

  before(): constructorInAnnotatedClass() && !cflowbelow(constructorInAnnotatedClass()) {
    final Object objectInstance = thisJoinPoint.getTarget();
    System.out.println("Object class name at join point: "
        + objectInstance.getClass().getName());
  }
}

@MyAnnotation(name="foo")
public class ClassA {
  public ClassA() {
    // Do something
  }

  public static void main(String[] args) {
    ClassA classA = new ClassA();
    ClassB classB = new ClassB("");
    if (classA.getClass().getName().equals(classB.getClass().getName())) {
        throw new RuntimeException("Big problems!");
    }
  }
}

@MyAnnotation(name="bar")
public class ClassB {
  private final String aString;

  public ClassB(String aString) {
    this.aString = aString;
  }
}
于 2012-08-31T03:36:19.873 回答