基于我自己的实验和这里的文档:http: //www.eclipse.org/aspectj/doc/released/faq.html#q :initializationjoinpoints
这个:
public class Init {
public static void main (String[] args) {
new Test();
}
}
@Inherited
@interface MyAnnotation {}
@MyAnnotation
class Super {}
class Test extends Super {
Test() {}
}
将导致:
<constructor-call sig="Test()" >
<staticinitialization sig="Super._init_" />
<staticinitialization sig="Test._init_" />
<initialization sig="Super()" >
<instanceinitializer-execution sig="Super._init_" />
<constructor-execution sig="Super()" />
</initialization>
<initialization sig="Test()" >
<instanceinitializer-execution sig="Test._init_" />
<constructor-execution sig="Test()" />
</initialization>
</constructor-call>
我正在尝试基于切入点创建建议,以便在实例完全构造后对实例执行操作,无论它是 Super 类型还是 Test 类型。
我试过这个:
pointcut initializedCall(): initialization((@MyAnnotation *).new(..));
after(Super s) returning: this(s) && initializedCall() {
System.out.println("after initialization via aspect");
}
但是在创建 Test 实例时它会被调用两次。在 Super 初始化后一次,然后在 Test 初始化后再次。
我试过这个:
pointcut constructorExecution(): execution((@MyAnnotation *).new(..));
after(Super s) returning : target(s) && constructorExecution() {
System.out.println("after constructor execution via aspect");
}
它也被调用了两次,创建了一个 Test 实例,与上面相同。
最后,我试过这个:
pointcut constructorCall(): call((@AutowiredClass *).new(..));
after(): constructorCall() {
System.out.println("after constructor call via aspect");
}
效果很好,因为它只被调用一次,但我不能在它上面使用 target() 来获取对新创建实例的引用,就像这里描述的那样。
有什么办法可以和上一次同时执行,而且还能获取到实例的引用吗?或者有没有办法判断方面是否会再次触发,以便我可以等到最后一次?
谢谢。
更新: 我还需要它来处理反射,因为我正在序列化和反序列化与 json 之间的类,并希望确保代码在反序列化期间的构造之后得到适当的执行。