-3

基于我自己的实验和这里的文档: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 之间的类,并希望确保代码在反序列化期间的构造之后得到适当的执行。

4

1 回答 1

0

如果您能够编织调用代码而不仅仅是执行代码,您可以使用call()切入点,但您需要一个around()建议,而不是after()为了将创建的对象绑定到变​​量并打印它或用它做任何其他事情:

import de.scrum_master.app.MyAnnotation;

public aspect ObjectConstructionInterceptor {
    pointcut constructorCall(): call((@MyAnnotation *).new(..));

    Object around() : constructorCall() {
        System.out.println(thisJoinPointStaticPart);
        Object createdObject = proceed();
        System.out.println("Created object = " + createdObject);
        return createdObject;
    }
}
于 2014-07-16T14:17:15.027 回答