minimize

事業拡大のため、新しい仲間を募集しています。
→詳しくはこちら

this

JoinPoint到達時のthis変数を限定・取得する場合に使います。

pointcut advice() : call(* *(..)) && this(SampleClass);

この場合、JoinPointはSampleClass内のコードから
メソッドを呼び出したときにJoinPointが設定されます。
ただし、staticメソッド内ではthis変数は存在しないので
この場合にはJoinPointは設定されません。

pointcut advice(SampleClass clazz) : call(* *(..)) && this(clazz);

JoinPointを設定する条件は前述のものと一緒ですが、
adviceにパラメータを一つ追加しています。
これは、メソッドを呼び出したときのthis変数(SampleClassのもの)になります。

execution

メソッドを実行する前後にJoinPointを設定します。
call とよく似ているのですが、若干動作が異なります。

JoinPointの位置

call はメソッドを呼び出す箇所にJoinPointが設定されるのに対し、
execution はメソッドそのものにJoinPointが設定されます。

void func1() {
    func2(); // callのJoinPointはここ
}
void func2() { // executionのJoinPointはここ
    ...
}
pointcut advice1() : call(void func2());
pointcut advice2() : execution(void func2());

within / withincode の挙動

JoinPointが変わることによって、いくつかのキーワードも挙動が変わってきます。

void func1() {
    func2(); // callのJoinPointはここ
}
void func2() {
    ...
}
pointcut advice1() : call(void func2()) && withincode(* func1(..));
pointcut advice2() : execution(void func2()) && withincode(* func1(..));
// advice2に当てはまるJoinPointは存在しない

withincode は、現在評価中のJoinPointが
特定のメソッド中に存在するかどうかを判断します。

advice1の場合、withincodeが解釈されるとき(callのみ解釈した段階)に
JoinPointはfunc1メソッド内に存在します。
よって、このとき withincode(* func1(..)) が成立するので
advice1のJoinPointは上の箇所になります。

一方advice2の場合、withincodeが解釈されるときのJoinPointは
func2メソッド内に存在します(「JoinPointの位置」参照)。
このとき withincode(* func1(..)) は成立しません。
よって、advice2に当てはまるJoinPointはこのコード中には存在しないことになります。

this の挙動

within のときと同じように、thisの挙動も変わります。