1

为了获得所有新实例化的小部件,我尝试了以下代码

after(final Widget widget) : execution (* Widget+.new(..)) && this(widget) {
    ...
}

但是每次有链式构造函数(同一个类中的多个构造函数,相互引用)时,它都会失败。

我需要收集在应用程序中创建的所有类型的小部件。我不能使用call代替,execution因为这意味着编织代码将成为调用代码的一部分,而不是Widget代码的一部分,这很麻烦,因为这个项目涉及很多库,这会让我不得不编织所有这些都是为了完成所描述的努力。

谢谢

编辑(更多信息)

考虑以下类:

class A {
  private int i;

  public A(int i) {
    this.i = i;
    initialize();
  }

  public A() {
    this(0);
  }
}

after(final A a) : execution (* A+.new(..)) && this(a) {
  ...
}

//test
new A(0); //caught by the aspect and fine
new A(); //caught by the aspect twice, once for every constructor.

如果考虑As 的层次结构,情况会变得更糟:

class B extends A {
  public B() {
    super();
  }

  public B(int i) {
    super(i);
  }
}

//test
new B(0); //caught by the aspect twice, once as B and once as A
new A(); //caught by the aspect thrice, once for B and twice for A

我只想捕获一次对象,并且只有在对象完全构造之后(也就是说,它已经将“外部”构造函数运行到最后),将方面代码注入到所考虑的类中而不是在它之外(所以 acall是不可接受的)。

我在 AspectJ 邮件列表中找到了关于此主题的另一个有趣的讨论:http: //dev.eclipse.org/mhonarc/lists/aspectj-users/msg09651.html。它描述了一个可能的(如果我没记错的话是不完整的)解决方案,涉及某种堆栈分析。

编辑2

这个简单的hack似乎可以解决问题:

after(A a) : initialization(A+.new(..)) && this(a) {
    if (a.getClass() == thisJoinPoint.getSignature().getDeclaringType())
                //fully constructed object caught
}
4

1 回答 1

0

在您的情况下,您应该能够使用初始化切入点。有关该切入点的更多信息,请参阅AspectJ 文档。本质上,您应该执行以下操作:

after(final A a) : initialization (* A+.new(..)) && this(a) {
  ...
}

这里的好处是你可以很棘手并指定一个特定的构造函数。在以下情况下,仅匹配 1-arg 构造函数。0-arg 构造函数不是。

initialization (* A+.new(int))
于 2013-04-25T20:51:11.573 回答