4

Spring のAspectJ @Async サポートを模倣しようとしていますが、メッセージ バスを使用しています。

問題は、メッセージ バス (RabbitMQ MessageListener) がメソッドを呼び出しているか、メソッドが即座に返される通常の (他のすべての) 呼び出し元を呼び出しているかを知る必要があることです。

私の注釈は、Springs @Async ではなく @MQAsync と呼ばれます。

package com.snaphop.mqueue;

import org.apache.log4j.Logger;
import com.snaphop.mqueue.MQAsync;

public aspect MQAsyncAspect {

    //pointcut asyncTypeMarkedMethod() : execution(@MQAsync void *(..));
    pointcut asyncTypeMarkedMethod() : call(@MQAsync void *(..));

    private static final Logger log = Logger.getLogger("MQAsync");

    Object around() : asyncTypeMarkedMethod() {     
        if (listenerIsCaller) {
            return proceed();
        }
        //Send the method parameters to the message bus.
        //this logic isn't here for brevity.
        return null;
    }
}

ポイントカットを呼び出すと呼び出し元のコンテキストが取得されますが、リフレクションを介してメッセージリスナーでメソッドを呼び出すため、これは機能しません。実行ポイントカット (コメント アウト) では、誰がメソッドを呼び出しているかわかりません。

おそらく何らかのスタックダンプ分析を通じて、呼び出し元クラスを特定する方法はありますか?

4

3 に答える 3

10

実際チーケンの答えは素晴らしいですが、AspectJcall()ポイントカットの場合、呼び出し元のクラスをはるかに簡単に取得でき、見苦しいリフレクションはありません:

thisEnclosingJoinPointStaticPart.getSignature().getDeclaringType()

他の回答よりも優れていると思われる場合は、この回答を受け入れることを検討してください。それ以外の場合は、AspectJ の力をお楽しみください。;-)

于 2015-04-05T16:55:56.773 に答える
8

次の呼び出しを使用して、現在のメソッドを呼び出しているクラスを特定できます。キャッチする必要があることに注意してくださいClassNotFoundException(単に名前を として取得することに満足しない限りString)。

Class.forName(Thread.currentThread().getStackTrace()[2].getClassName());

なぜ3番目の要素?スタック トレース メソッドが呼び出されると、スタックは次のように順序付けられるため:

  1. Thread#getStackTrace()
  2. CurrentClass.currentMethod()
  3. ParentClass.parentMethod()
于 2012-06-07T04:38:58.070 に答える
0

これは、SecurityManager によってネイティブで一般的に使用されているため、より軽量に見える代替手段です。これを使用するには、必要なメソッドが保護されているため、ユーティリティ クラスが必要です。

public class CallStackUtils extends SecurityManager {

  static CallStackUtils sm = new CallStackUtils();

  public Class[] getCallersClassesStack0() {
    return getClassContext();
  }

  static public Class[] getCallersClassesStack() {
    return sm.getCallersClassesStack0();
  }

}
于 2015-03-26T13:50:14.563 に答える