web-dev-qa-db-ja.com

AspectJポイントカット-ジョインポイントクラスと名前への参照を取得します

アプリケーションのロギングを処理するために、アスペクトの記述に@AspectJスタイルを使用しています。基本的に、私は次のようにポイントカットを設定しています。

@Pointcut("call(public * com.example..*(..))")
public void logging() {}

そして、そのようなアドバイスの前後に:

@Before("logging()")
public void entering() {...}
...
@After("logging()")
public void exiting() {...}

これらのメソッドで次の形式でログを作成したいと思います。

logger.trace("ENTERING/EXITING [" className + "." + methodName "()]");

問題は、クラス名とメソッド名への参照を取得する方法がわからないことです。私が試してみました:

joinPoint.getThis().getClass()

しかし、これは呼び出し元のクラス名を返すようです。

class A {
    public void a() {
        B.b();
    }
}


class B {
    public void b() {
        ...
    }
}

次のログになります

ENTERING [A.b()]

誰かが実際のジョインポイントクラスとメソッド名を取得する方法について助けを与えることができますか

22
smauel

joinPoint.getTarget().getClass()を使用する必要があります。コール参加ポイントのアドバイスを使用しているため、関心のあるオブジェクトがコールのターゲットになります。

API仕様の状態 に注意してください:

ターゲットオブジェクトを返します。これは常に、ターゲットポイントカット指定子によって一致したオブジェクトと同じオブジェクトになります。このリフレクティブアクセスが特に必要でない限り、静的な型指定とパフォーマンスを向上させるために、ターゲットポイントカット指定子を使用してこのオブジェクトに到達する必要があります。

ターゲットオブジェクトがない場合はnullを返します。

盲目的にjoinPoint.getTarget().getClass()を使用すると、NullPointerExceptionになる可能性があります。次のようなジョインポイントの署名の使用を検討してください。

final Signature signature = joinPoint.getSignature();

次に:

final Class clazz = signature.getDeclaringType();

または、必要なのがクラス名だけの場合:

final String clazz = signature.getDeclaringTypeName();
37
ramnivas
    public void logBefore(JoinPoint joinPoint) {
    logger.info("###### Requested class : {} ; Method : {} ", joinPoint.getTarget().getClass().getName(), joinPoint.getSignature().getName());
    Object[] signatureArgs = joinPoint.getArgs();
    for (Object signatureArg : signatureArgs) {
        logger.info("###### Arguments: {} ", signatureArg.toString());
    }
} 

誰かを助けるかもしれません:上記のコードを使用して、要求されたクラス、メソッド、および引数を取得します。

2