1. 概要

このチュートリアルでは、 AspectJ を使用して、構成されたクラスのメソッドを呼び出すときにトレースログ出力を書き込みます。 AOPアドバイスを使用してトレースログ出力を書き込むことにより、ロジックを単一のコンパイル単位にカプセル化します。

この例は、 Intro toAspectJで提示された情報を拡張したものです。

2. トレースロギングアノテーション

アノテーションを使用してクラスを構成し、メソッド呼び出しをトレースできるようにします。アノテーションを使用すると、ロギングステートメントを直接追加しなくても、トレースロギング出力を新しいコードに追加する簡単なメカニズムが得られます。

注釈を作成しましょう:

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface Trace {
}

3. アスペクトの作成

関心のあるジョインポイントと実行するロジックを含むaroundアドバイスに一致するように、pointcutを定義するアスペクトを作成します。

私たちの側面はこれに似ています:

public aspect TracingAspect {
    private static final Log LOG = LogFactory.getLog(TracingAspect.class);

    pointcut traceAnnotatedClasses(): within(@Trace *) && execution(* *(..));

    Object around() : traceAnnotatedClasses() {
        String signature = thisJoinPoint.getSignature().toShortString();
        LOG.trace("Entering " + signature);
        try {
            return proceed();
        } finally {
            LOG.trace("Exiting " + signature);
        }
    }
}

この側面では、Trace[で注釈が付けられたクラス内のメソッド実行と一致するtraceAnnotatedClassesという名前のポイントカットを定義します。 X177X]注釈。 ポイントカットを定義して名前を付けることで、クラスのメソッドと同じように再利用できます。この名前のポイントカットを使用して、周辺のアドバイスを構成します。

ポイントカットに一致するジョインポイントの代わりにアラウンドアドバイスが実行され、オブジェクトが返されます。 Object リターンタイプを使用することで、任意のリターンタイプのアドバイスメソッドを考慮することができます。 、voidですら。

一致したジョインポイントの署名を取得して、署名の短い String 表現を作成し、トレースメッセージにコンテキストを追加します。 その結果、ロギング出力にはクラスの名前と実行されたメソッドが含まれ、必要なコンテキストが得られます。

トレース出力呼び出しの間に、progressという名前のメソッドを呼び出しました。 このメソッドは、一致したジョインポイントの実行を継続するためのアドバイスに利用できます。 返品タイプは物体コンパイル時に戻り型を知る方法がないためです。 最終トレース出力をログに送信した後、この値を呼び出し元に送り返します。

exit()呼び出しをtry / finalブロックでラップして、終了メッセージが書き込まれるようにします。スローされた例外をトレースする場合は、 after()アドバイスを追加できます。例外がスローされたときにログメッセージを書き込みます。

after() throwing (Exception e) : traceAnnotatedClasses() {
    LOG.trace("Exception thrown from " + thisJoinPoint.getSignature().toShortString(), e);
}

4. コードに注釈を付ける

次に、トレースを有効にする必要があります。 簡単なクラスを作成し、カスタムアノテーションを使用してトレースログをアクティブ化しましょう。

@Trace
@Component
public class MyTracedService {

    public void performSomeLogic() {
        ...
    }

    public void performSomeAdditionalLogic() {
        ...
    }
}

Trace アノテーションを設定すると、クラスのメソッドは、定義したpointcutと一致します。 これらのメソッドが実行されると、トレースメッセージがログに書き込まれます。

これらのメソッドを呼び出すコードを実行した後、ログ出力には次のようなコンテンツが含まれるはずです。

22:37:58.867 [main] TRACE c.b.a.c.TracingAspect - Entering MyTracedService.performSomeAdditionalLogic()
22:37:58.868 [main] INFO  c.b.a.c.MyTracedService - Inside performSomeAdditionalLogic...
22:37:58.868 [main] TRACE c.b.a.c.TracingAspect - Exiting MyTracedService.performSomeAdditionalLogic()
22:37:58.869 [main] TRACE c.b.a.c.TracingAspect - Entering MyTracedService.performSomeLogic()
22:37:58.869 [main] INFO  c.b.a.c.MyTracedService - Inside performSomeLogic...
22:37:58.869 [main] TRACE c.b.a.c.TracingAspect - Exiting MyTracedService.performSomeLogic()

5. 結論

この記事では、AspectJを使用して、クラスのすべてのメソッドをクラスの単一のアノテーションでインターセプトしました。 そうすることで、トレースロギング機能を新しいコードにすばやく追加できます。

また、トレースロギング出力ロジックを単一のコンパイルユニットに統合して、アプリケーションの進化に合わせてトレースロギング出力を変更する機能を向上させました。

いつものように、記事の完全なソースコードは、GitHubから入手できます。