AspectJ を使用してオブジェクトが作成された時刻を追跡する必要がある場合、コンストラクターへの呼び出し、コンストラクターの実行、またはオブジェクトの初期化をキャプチャしますか? 3 つの構文はすべて、それぞれpointcut: call
、 、pointcut: execution
と異なりpointcut: initialization
ます。
3つすべての違いと、どれが完璧に使用できるでしょうか?
AspectJ を使用してオブジェクトが作成された時刻を追跡する必要がある場合、コンストラクターへの呼び出し、コンストラクターの実行、またはオブジェクトの初期化をキャプチャしますか? 3 つの構文はすべて、それぞれpointcut: call
、 、pointcut: execution
と異なりpointcut: initialization
ます。
3つすべての違いと、どれが完璧に使用できるでしょうか?
ポイントカットが対処するジョインポイントをよりよく理解するには、次の簡単な例が役立ちます。
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
...
したがって、オブジェクトの初期化の時点を、コンストラクターが呼び出された瞬間から、実行が呼び出されたのと同じスコープに戻る瞬間までの時間と見なす場合、これは方法かもしれません。
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
私はここで同様の質問に答えました: How to crosscut annotated Methods and constructors?
おそらく、これはアンドリューがすでに指摘したことを明確にするのに役立ちます. 回答には、説明付きの小さなコード サンプルが含まれています。