为了获取所有新实例化的小部件,我尝试了以下代码
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
我只想捕获一次对象,并且只在对象完全构造之后(也就是说,它已经将“外部”构造函数运行到最后),作为注入到正在考虑的类中的方面代码不在它之外(因此call
是不可接受的)。
有一个有趣的讨论我在AspectJ邮件列表上找到了另一个关于这个主题的讨论:http://dev.eclipse.org/mhonarc/lists/aspectj-users/msg09651.html。它描述了一种可能的(非完整的,如果我没有错)解决方案,涉及某种堆栈分析。
这种简单的黑客似乎可以解决问题:
after(A a) : initialization(A+.new(..)) && this(a) {
if (a.getClass() == thisJoinPoint.getSignature().getDeclaringType())
//fully constructed object caught
}
答案 0 :(得分:0)
在您的情况下,您应该能够使用初始化切入点。有关该切入点的更多信息,请参阅AspectJ docs。基本上,你应该做这样的事情:
after(final A a) : initialization (* A+.new(..)) && this(a) {
...
}
这里的好处是你可能会很棘手,并指定一个特定的构造函数。在以下情况中,仅匹配1-arg构造函数。 0-arg constrcutor不是。
initialization (* A+.new(int))