3

注釈は次のとおりです。

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

注釈付きクラスの 1 つを次に示します。

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

2 番目の注釈付きクラスを次に示します。

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

ClassA および ClassB のコンストラクターに正しく一致するが、 で注釈が付けられていない他のクラスの他のコンストラクターには一致しない、aspectj ポイントカットを探しています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 に答える