Micronautのインターセプタとは?処理の前後を制御する仕組みを解説
生徒
「MicronautのAOPを勉強していたら、インターセプタという言葉が出てきました。これは何をする仕組みなんですか?」
先生
「インターセプタは、メソッドの処理の前や後に、別の処理を差し込むための仕組みです。AOPを実現する中心的な役割を持っています。」
生徒
「つまり、メソッドの中身を書き換えずに、動きを変えられるということですか?」
先生
「そうです。ログ出力やチェック処理などを、インターセプタでまとめて管理できます。では、仕組みを順番に見ていきましょう。」
1. Micronautにおけるインターセプタの基本概念
Micronautのインターセプタは、AOPを実現するための重要なコンポーネントです。特定のメソッドが呼び出される前後に処理を挟み込むことで、共通処理を実装できます。
初心者が最初に書くアプリケーションでは、ログ出力や簡単なチェック処理を、各メソッドに直接書きがちです。しかし、インターセプタを使えば、それらの処理を一か所に集約でき、コードの見通しが良くなります。
2. インターセプタとAOPの関係
Micronautでは、AOPという考え方の中でインターセプタが使われます。AOPは仕組み全体を指す言葉で、インターセプタは実際に処理を実装する役割を担います。
アノテーションによって対象となるメソッドが指定され、そのアノテーションに対応したインターセプタが呼び出される、という流れで動作します。この構造を理解すると、MicronautのAOPが一気に分かりやすくなります。
3. インターセプタで処理の前後を制御する仕組み
インターセプタは、メソッド呼び出しを包み込むように動作します。処理の前に実行される部分、元のメソッド処理、処理の後に実行される部分という順番です。
この仕組みにより、元のメソッドには一切手を加えずに、振る舞いだけを追加できます。これが、Micronautにおけるインターセプタの最大の特徴です。
4. シンプルなインターセプタ用アノテーションの例
まずは、インターセプタを適用するためのシンプルなアノテーションを作成します。ここでは、処理の前後でメッセージを表示する用途を想定します。
import io.micronaut.aop.Around;
import java.lang.annotation.*;
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD, ElementType.TYPE})
@Around
public @interface SimpleInterceptor {
}
このアノテーションは、どのメソッドにインターセプタを適用するかを示すための目印になります。
5. インターセプタクラスの基本的な実装例
次に、実際に処理の前後を制御するインターセプタクラスを作成します。初心者でも読みやすい、シンプルな内容にしています。
import io.micronaut.aop.InterceptorBean;
import io.micronaut.aop.MethodInterceptor;
import io.micronaut.aop.MethodInvocationContext;
import jakarta.inject.Singleton;
@Singleton
@InterceptorBean(SimpleInterceptor.class)
public class SimpleInterceptorImpl implements MethodInterceptor<Object, Object> {
@Override
public Object intercept(MethodInvocationContext<Object, Object> context) {
System.out.println("メソッド実行前");
Object result = context.proceed();
System.out.println("メソッド実行後");
return result;
}
}
context.proceedを呼び出すことで、本来のメソッド処理が実行されます。この前後に自由に処理を追加できます。
6. サービスクラスにインターセプタを適用する例
作成したインターセプタを、実際のサービスクラスで使ってみます。業務ロジックはできるだけ単純にしています。
import jakarta.inject.Singleton;
@Singleton
public class OrderService {
@SimpleInterceptor
public void createOrder() {
System.out.println("注文処理を実行します");
}
}
このメソッドを呼び出すと、注文処理の前後でインターセプタの処理が実行されます。サービスクラスは、本来の役割だけを意識すればよくなります。
7. インターセプタを使った処理時間計測の考え方
インターセプタは、処理時間の計測にもよく使われます。開始時刻と終了時刻を取得し、その差分を出力するだけで、簡単なパフォーマンス確認ができます。
@Singleton
@InterceptorBean(SimpleInterceptor.class)
public class TimeLoggingInterceptor 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;
}
}
このように、同じ仕組みを使って、さまざまな用途に応用できるのがインターセプタの強みです。
8. 初心者がインターセプタを使うときの注意点
Micronautのインターセプタは非常に便利ですが、使いすぎると処理の流れが分かりにくくなることがあります。業務ロジックとは直接関係のない共通処理に限定して使うことが大切です。
まずはログ出力や簡単な計測処理など、動きが目に見えて分かるものから使うと、インターセプタの仕組みを理解しやすくなります。