MicronautでアノテーションAOPを使う方法!基本の@Aroundを理解しよう
生徒
「Micronautの勉強をしていたら、@Aroundというアノテーションが出てきました。これは何に使うものなんですか?」
先生
「Micronautでは、共通処理をまとめて扱うためにAOPという仕組みがあります。その中心になるのが@Aroundです。」
生徒
「共通処理というのは、ログ出力とかですか?」
先生
「そうですね。ログや処理時間の計測などを、業務処理とは分けて書けるのが特徴です。順番に見ていきましょう。」
1. MicronautにおけるアノテーションAOPとは
MicronautのアノテーションAOPは、特定のメソッドやクラスに対して、処理の前後に別の処理を差し込むための仕組みです。初心者が最初に戸惑いやすいポイントですが、考え方はとてもシンプルです。
通常のJavaプログラムでは、ログ出力やチェック処理をメソッドの中に直接書きます。しかし、その方法では同じコードを何度も書くことになり、修正が大変になります。MicronautのAOPを使うことで、こうした共通処理を一か所にまとめることができます。
2. @Aroundが果たす役割と基本的な動き
@Aroundは、MicronautのAOPを実現するための重要なアノテーションです。このアノテーションが付いたアノテーションは、メソッドの実行前後を包み込むように処理を実行します。
Micronautでは、実行時ではなくコンパイル時にAOPの処理が組み込まれます。そのため、起動が速く、メモリ使用量も抑えられるという特徴があります。マイクロサービスやクラウド環境と相性が良い理由の一つです。
3. @Aroundを使ったカスタムアノテーションの作り方
まずは、@Aroundを使った独自アノテーションを作成します。ここでは、処理の前後でメッセージを表示するシンプルな例を見ていきます。
import io.micronaut.aop.Around;
import java.lang.annotation.*;
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD, ElementType.TYPE})
@Around
public @interface SimpleAround {
}
このアノテーション自体には処理内容は書きません。どの処理にAOPを適用するかを示す目印の役割を持っています。
4. インターセプタで処理内容を定義する
次に、@Aroundで指定された処理を実際に動かすためのインターセプタを作成します。インターセプタでは、メソッドの前後に行いたい処理を記述します。
import io.micronaut.aop.InterceptorBean;
import io.micronaut.aop.MethodInterceptor;
import io.micronaut.aop.MethodInvocationContext;
import jakarta.inject.Singleton;
@Singleton
@InterceptorBean(SimpleAround.class)
public class SimpleAroundInterceptor 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を呼び出すことで、本来のメソッド処理が実行されます。この前後に自由に処理を書けるのがAOPの強みです。
5. サービスクラスでアノテーションAOPを使う例
作成したアノテーションを、実際のサービスクラスで使ってみます。業務ロジックはとてもシンプルな内容にしています。
import jakarta.inject.Singleton;
@Singleton
public class SampleService {
@SimpleAround
public String message(String name) {
return "こんにちは、" + name;
}
}
このメソッドが呼び出されると、自動的にインターセプタが動作し、処理の前後にメッセージが出力されます。サービス側は本来の役割だけに集中できます。
6. 複数メソッドに共通処理を適用するメリット
@Aroundを使ったアノテーションAOPは、複数のメソッドに同じ処理を簡単に適用できます。ログ出力や簡単なチェック処理を、何度も書く必要がなくなります。
特に初心者のうちは、クラスが増えるにつれてコードが読みにくくなりがちです。AOPを使うことで、構造が整理され、後から読み返したときにも理解しやすくなります。
7. 処理時間を計測する簡単なAOPの例
次は、処理時間を測定する簡単なAOPの例です。考え方は同じで、前後の処理に時間計測を追加します。
@Singleton
@InterceptorBean(SimpleAround.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;
}
}
このように、処理内容を差し替えるだけで、さまざまな用途にAOPを応用できます。
8. 初心者が意識したいアノテーションAOPの使いどころ
MicronautのアノテーションAOPはとても便利ですが、何でもAOPで書けばよいわけではありません。業務ロジックと関係のない共通処理に限定して使うことが大切です。
最初はログ出力や簡単な計測処理など、動きが分かりやすい用途から使うと理解が深まります。MicronautのAOPと@Aroundを正しく使えるようになると、保守性の高いアプリケーションを書けるようになります。