Micronaut AOPのエラー対策!よくある問題と解決方法まとめ
生徒
「MicronautでAOPを使ったらエラーが出てしまいました。Interceptorの設定に問題があるのでしょうか?」
先生
「MicronautのAOPでは、よくあるエラーの原因としてBeanの未登録やアノテーションの付け方の間違いがあります。順を追って確認していきましょう。」
生徒
「どのようなパターンが多いですか?」
先生
「典型的には、InterceptorがSingletonとして登録されていない場合や、メソッドの戻り値やパラメータがAOPで扱えない型になっているケースです。」
1. InterceptorがBeanとして認識されない問題
MicronautのAOPを使う場合、Interceptorクラスは必ず@SingletonなどのBeanスコープを付与して登録する必要があります。登録されていない場合、アプリケーション起動時にInterceptorが見つからずエラーになります。
import io.micronaut.aop.MethodInterceptor;
import io.micronaut.aop.MethodInvocationContext;
import jakarta.inject.Singleton;
@Singleton
public class LoggingInterceptor 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;
}
}
2. メソッドシグネチャの不一致によるエラー
Interceptorが対象とするメソッドの戻り値やパラメータが、Interceptorのジェネリック型と一致していない場合、型変換エラーが発生します。特にvoidメソッドやプリミティブ型は注意が必要です。
@Timed
public void processTask(String taskName) {
System.out.println("タスク処理: " + taskName);
}
3. 複数Interceptorの順序指定の問題
Micronautでは複数のInterceptorを同じメソッドに適用できますが、@Aroundアノテーションの順序が不適切だと、Interceptorが想定通りに実行されません。順序を意識して@Orderを使用すると解決できます。
import io.micronaut.core.order.Ordered;
import io.micronaut.aop.Around;
@Around(Order = Ordered.HIGHEST_PRECEDENCE)
public @interface SecurityCheck {}
4. Bean注入の失敗によるエラー
Interceptor内部で他のBeanを@Injectしようとしても、Beanが正しくスキャンされていないとNullPointerExceptionが発生します。必ず@Componentや@SingletonでBeanを登録し、Interceptor側で@Injectして利用します。
@Singleton
public class MetricsService {
public void record(String metric) {
System.out.println("メトリクス記録: " + metric);
}
}
5. AOPアノテーションの適用範囲の誤り
クラス全体に@Aroundアノテーションを付けたつもりでも、対象メソッドがプライベートやファイナルだとAOPが適用されません。AOPは公開メソッド(public)や非ファイナルクラスを対象にする必要があります。
@Timed
public class TaskProcessor {
public void execute(String task) {
System.out.println("タスク: " + task);
}
}
6. 実行時例外の補足とエラー対策
Interceptor内で例外が発生した場合、呼び出し元に例外が伝播します。try-catchで適切に補足してログ出力やリトライ処理を行うことで、アプリケーションの安定性が向上します。
@Override
public Object intercept(MethodInvocationContext<Object, Object> context) {
try {
return context.proceed();
} catch (Exception e) {
System.out.println("エラー発生: " + e.getMessage());
throw e;
}
}
7. AOP導入前に確認するポイント
MicronautでAOPを利用する前には、InterceptorのBean登録、メソッドの公開範囲、戻り値型、依存Beanの登録状況、複数Interceptorの順序などを事前に確認することが重要です。これにより、起動時や実行時のエラーを未然に防げます。