如果我需要跟踪创建对象的时间,使用AspectJ,我是否捕获对构造函数的调用,执行构造函数或对象初始化?这三种语法分别具有不同的语法:pointcut: call
,pointcut: execution
和pointcut: initialization
。
这三者之间有什么区别,哪一种最适合使用?
答案 0 :(得分:0)
这3个切入点重叠,但具有不同的语义。来自AspectJ programming guide:
由于我不确定你要做什么,我不能建议哪个最有意义,但如果你想知道创建一个对象需要多少时间,那么使用执行切入点最有意义。
答案 1 :(得分:0)
我在这里回答了类似的问题:How to crosscut annotated methods and constructors?
也许这有助于澄清安德鲁已经指出的内容。答案包含一些代码示例和解释。
答案 2 :(得分:0)
为了更好地理解切入点将要解决的连接点,这个简单的示例可以帮助您:
class C {
public void foo() {
System.out.println("foo");
}
}
public class Main {
public static void main(String[] args) {
C c = new C();
c.foo();
}
}
现在让我们有一个方面打印所有可能的连接点,可以在之前用和之后的更改:
public aspect MyAspect {
pointcut Anything() :
cflow(!within(MyAspect)) && !within(MyAspect);
before() : Anything() {
System.out.println("before " + thisJoinPoint);
}
after() : Anything() {
System.out.println("after " + thisJoinPoint);
}
}
产生以下输出:
...
before call(C()) // <-- call to constructor, new C()
before staticinitialization(C.<clinit>)
after staticinitialization(C.<clinit>)
before preinitialization(C())
after preinitialization(C())
before initialization(C())
before execution(C()) // <-- actual execution of constructor
after execution(C())
after initialization(C())
after call(C()) // <-- after call to constructor
...
因此,如果您将对象的初始化时间视为从构造函数被调用的那一刻起,直到执行返回到调用它的同一范围,这可能是一种方法:< / p>
public aspect ConstructionTiming {
private long startTime, endTime;
before() : call(C.new(..)) {
startTime = System.nanoTime();
}
after() : call(C.new(..)) {
endTime = System.nanoTime();
System.out.println("construction took " +
(endTime - startTime)/1e6 + "ms");
}
}
在我的案例中输出了construction took 0.64879ms