カテゴリ: Micronaut 更新日: 2026/02/09

MicronautのMethodInterceptorの使い方!独自ロジックを挟む基本と応用

MicronautのMethodInterceptorの使い方!独自ロジックを挟む基本と応用
MicronautのMethodInterceptorの使い方!独自ロジックを挟む基本と応用

先生と生徒の会話形式で理解しよう

生徒

「MicronautのAOPで、MethodInterceptorというクラスをよく見かけますが、これは何をするものなんですか?」

先生

「MethodInterceptorは、メソッドの実行前後に独自の処理を挟むための仕組みです。MicronautのAOPを実現する中心的な存在ですね。」

生徒

「前後に処理を挟めるということは、ログやチェック処理も書けるんですか?」

先生

「その通りです。基本を押さえれば、いろいろな共通処理を安全に追加できます。順番に見ていきましょう。」

1. MethodInterceptorとは何か

1. MethodInterceptorとは何か
1. MethodInterceptorとは何か

MicronautのMethodInterceptorは、AOPの仕組みの中で実際に処理を行うためのインターフェースです。特定のメソッドが呼び出されるタイミングで、処理の前後に独自ロジックを追加できます。

初心者が最初に理解しておきたいポイントは、MethodInterceptor自体が業務ロジックを書く場所ではないという点です。あくまで、ログ出力や処理時間の計測など、複数のクラスで共通して使いたい処理をまとめるために利用します。

2. MicronautのAOPとMethodInterceptorの関係

2. MicronautのAOPとMethodInterceptorの関係
2. MicronautのAOPとMethodInterceptorの関係

Micronautでは、AOPという考え方の中でMethodInterceptorが使われます。AOPは全体の仕組みを指し、MethodInterceptorは実装の中心となる部品です。

アノテーションによって対象となるメソッドが指定され、そのアノテーションに対応するMethodInterceptorが呼び出されます。この流れを理解することで、MicronautのAOP構造が自然と見えてきます。

3. MethodInterceptorの基本的な動作の流れ

3. MethodInterceptorの基本的な動作の流れ
3. MethodInterceptorの基本的な動作の流れ

MethodInterceptorは、メソッド呼び出しを包み込むように動作します。まずメソッド実行前の処理が行われ、その後に本来のメソッドが実行され、最後にメソッド実行後の処理が行われます。

この一連の流れにより、元のコードを変更することなく、処理の振る舞いだけを追加できます。これがAOPとMethodInterceptorの大きなメリットです。

4. MethodInterceptor用アノテーションの作成例

4. MethodInterceptor用アノテーションの作成例
4. MethodInterceptor用アノテーションの作成例

まずは、MethodInterceptorを適用するためのアノテーションを作成します。ここでは、処理の前後でメッセージを表示するためのシンプルなアノテーションを用意します。


import io.micronaut.aop.Around;
import java.lang.annotation.*;

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD, ElementType.TYPE})
@Around
public @interface MethodLog {
}

このアノテーションは、どのメソッドにMethodInterceptorを適用するかを示すための目印になります。

5. MethodInterceptorの基本的な実装方法

5. MethodInterceptorの基本的な実装方法
5. MethodInterceptorの基本的な実装方法

次に、MethodInterceptorを実装したクラスを作成します。ここでは、メソッドの実行前後でログを出力する例を示します。


import io.micronaut.aop.InterceptorBean;
import io.micronaut.aop.MethodInterceptor;
import io.micronaut.aop.MethodInvocationContext;
import jakarta.inject.Singleton;

@Singleton
@InterceptorBean(MethodLog.class)
public class MethodLogInterceptor implements MethodInterceptor<Object, Object> {

    @Override
    public Object intercept(MethodInvocationContext<Object, Object> context) {
        System.out.println("メソッド開始: " + context.getMethodName());
        Object result = context.proceed();
        System.out.println("メソッド終了: " + context.getMethodName());
        return result;
    }
}

context.proceedを呼び出すことで、本来のメソッド処理が実行されます。この呼び出しを忘れると、元の処理が実行されない点に注意が必要です。

6. サービスクラスでMethodInterceptorを使う例

6. サービスクラスでMethodInterceptorを使う例
6. サービスクラスでMethodInterceptorを使う例

作成したMethodInterceptorを、実際のサービスクラスで使ってみます。業務ロジックはできるだけ単純にして、動きが分かりやすい例にしています。


import jakarta.inject.Singleton;

@Singleton
public class UserService {

    @MethodLog
    public String createUser(String name) {
        return "ユーザー作成: " + name;
    }
}

このメソッドが呼び出されると、メソッド開始と終了のログが自動的に出力されます。UserService自体は、本来の処理だけを書けばよくなります。

7. MethodInterceptorを使った処理時間計測の応用例

7. MethodInterceptorを使った処理時間計測の応用例
7. MethodInterceptorを使った処理時間計測の応用例

MethodInterceptorは、処理時間の計測にもよく使われます。開始時刻と終了時刻を取得し、その差を出力することで、簡単なパフォーマンス確認ができます。


@Singleton
@InterceptorBean(MethodLog.class)
public class TimeMeasureInterceptor implements MethodInterceptor<Object, Object> {

    @Override
    public Object intercept(MethodInvocationContext<Object, Object> context) {
        long start = System.currentTimeMillis();
        Object result = context.proceed();
        long end = System.currentTimeMillis();
        System.out.println("実行時間: " + (end - start) + "ms");
        return result;
    }
}

このように、同じ仕組みを使ってさまざまな独自ロジックを挟めるのがMethodInterceptorの魅力です。

8. 初心者がMethodInterceptorを使うときの考え方

8. 初心者がMethodInterceptorを使うときの考え方
8. 初心者がMethodInterceptorを使うときの考え方

MethodInterceptorは非常に便利ですが、何でもここに書くとコードの流れが分かりにくくなります。業務ロジックとは直接関係のない共通処理に限定して使うことが重要です。

最初はログ出力や簡単な計測処理など、動きが目で確認できる用途から始めると、MicronautのAOPとMethodInterceptorの理解が深まります。

カテゴリの一覧へ
新着記事
New1
Micronaut
Micronautの@Factoryとは?複雑なBean生成を管理するための方法を解説
New2
Quarkus
QuarkusのDIとCDIを完全理解!@Producesでプロデューサーメソッドを使う方法を初心者向けに解説
New3
Java
JavaのStringBufferクラスを徹底解説!スレッド安全な文字列操作の仕組みと使い分け
New4
Micronaut
Micronautで非同期HTTP処理を行う方法!リアクティブ対応の基礎知識
人気記事
No.1
Java&Spring記事人気No1
Quarkus
Quarkus入門!GitHub ActionsでCI/CDパイプラインを構築して自動ビルドを実現する方法
No.2
Java&Spring記事人気No2
Java
Javaのコンパイルと実行の流れを解説!JVM・JDK・JREの違いも初心者向けに整理
No.3
Java&Spring記事人気No3
Quarkus
QuarkusのCI/CD入門!GitHub Actionsで自動デプロイを実現する方法
No.4
Java&Spring記事人気No4
Micronaut
Micronautのルーティング設定ガイド!プレフィックス付与とAPIバージョニングの基本
No.5
Java&Spring記事人気No5
Micronaut
Micronautのフィルタ徹底解説!HTTPリクエスト共通処理をスマートに追加する方法
No.6
Java&Spring記事人気No6
Java
Java Optional ifPresentの使い方を徹底解説!nullチェックをスマートに省略する方法
No.7
Java&Spring記事人気No7
Java
Java Functionインタフェースの使い方を完全ガイド!map変換と処理チェーンを理解する
No.8
Java&Spring記事人気No8
Java
JavaのString比較を徹底解説!equalsと==の違い、初心者が陥る罠とは?