为了获得所有新实例化的小部件,我尝试了以下代码
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.
如果考虑A
s 的层次结构,情况会变得更糟:
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
}