web-dev-qa-db-ja.com

実行対。ジョインポイントを呼び出す

テストプログラムを実行するための非静的メソッド呼び出しの数をカウントするために、2つの異なるアスペクトクラスがあります。最初の側面は、「コール」ジョインポイントのメソッドをカウントします。

pointcut methodCalls() : call (!static * test..*(..));
before(): methodCalls() {
        counter.methodCallCounter();
}

2番目の側面では、「実行」ジョインポイントのメソッドをカウントします。

pointcut methodCalls() : execution (!static * test..*(..));
before(): methodCalls() {
        counter.methodCallCounter();
}

methodCallCounter()は、カウンタークラスの静的メソッドです。

小さなテストプログラムのメソッド呼び出しの数は同じです。しかし、より大きなプログラムでテストプログラムを変更すると、2番目のアスペクトクラス(実行ポイントカットを使用)のメソッド呼び出しの数は、呼び出しポイントカットを使用したアスペクトクラスのメソッド呼び出しの数よりも多くなります。コールジョインポイントはsuperで行われたコールを選択せず​​、したがってそれらをカウントしないため、これは合理的です。

しかし、プログラムの特定の実行で、「callpointcut」を使用したアスペクトクラスの非静的メソッド呼び出しの数が「executionpointcut」を使用したアスペクトクラスのメソッド呼び出しの数よりも多い場合がありました。なぜこれが起こっているのか、私には解釈が見つかりません。 2番目の状況の理由についての考えはありがたいです。

21
user1843337

call()execution()ポイントカットの基本的な違いを理解していれば、説明は非常に簡単です。前者はすべての呼び出し元(つまり、メソッド呼び出しのソース)をインターセプトしますが、後者は呼び出しをインターセプトします。彼らがどこから来たとしても、彼ら自身。

では、両方のポイントカットによってトリガーされるインターセプトの数はどのように異なるのでしょうか。

  • 独自のコードからJRE/JDKメソッドを呼び出す場合、AspectJは呼び出しに織り込むことはできますが、JDK内の実行結合点に織り込むことはできません(準備ステップとして織り込まれたJDKを作成した場合を除く)。したがって、呼び出しの数は実行の数よりも多くなります。
  • 同様に、LTWまたはCTW中にパス上になかったために、AspectJで織り込まれていないサードパーティライブラリのメソッドを呼び出すと、実行はキャプチャされません。
  • 最後になりましたが、独自の織りコードがサードパーティのライブラリまたはJRE/JDKクラスによって呼び出された場合は、逆に発生する可能性があります。この場合、実行のカウント数は、AspectJコードの制御外の場所から発生するため、呼び出しの数よりも多くなります。

一般に、すべての場合において、理由は、全体的に使用されるコードと織り込まれたコードのサブセットの違いです。言い換えれば、あなた(またはアスペクト)の制御下と制御外のコードの違いです。

43
kriegaex