AOPとは、Aspect Oriented Programming(アスペクト指向プログラミング)の略称で、横断的な関心事(クロスカッティングコンセルン)をモジュール化する手法です。Spring FrameworkはAOPをサポートしており、AspectJという専用のAOPフレームワークを利用しています。
クロスカッティングコンセルンとは
クロスカッティングコンセルンとは、アプリケーションの機能から分離された、横断的に行われる処理のことです。代表的なものとしては以下のようなものがあげられます。
- ログ出力
- 例外処理
- トランザクション管理
- 権限・認証管理
こういった横断的な処理は、アプリケーションの中から切り離してモジュール化することができます。これがAOPの目的です。
Spring AOPの構成要素
Spring AOPには以下の構成要素があります。
- Aspect: クロスカッティングコンセルンを実装したモジュール
- Advice: Aspectの具体的な処理ロジックを実装したメソッド
- Pointcut: Adviceが適用される対象(Joinpoint)を特定するための式
- JoinPoint: メソッド実行時、例外発生時などの実行ポイント
- Target Object: Adviceが適用されるオブジェクト
具体例
ログ出力機能を実装する際のAOPの具体例を見てみましょう。
// LoggingAspect.java
@Aspect
@Component
public class LoggingAspect {
// Pointcut定義
@Pointcut("execution(* com.example.service.*.*(..))")
private void loggingPointcut() {}
// ログ出力Advice
@Before("loggingPointcut()")
public void logBefore(JoinPoint joinPoint) {
System.out.println("Method:" + joinPoint.getSignature().getName());
}
}
// EmailService.java
@Service
public class EmailService {
public void sendEmail(String email, String body) {
// 実装...
}
}
LoggingAspectクラスがAspectとなります。@Aspectアノテーションを付与することで、このクラスがAspectであることを宣言しています。
loggingPointcut()メソッドは、com.example.serviceパッケージ内のすべてのメソッドを対象とするPointcutを定義しています。
logBefore()メソッドがAdviceとなり、PointcutでマッチしたJoinPoint(メソッド実行時)の前にこのメソッドが実行されます。
EmailServiceクラスは、Target Objectとなります。sendEmail()メソッドが実行される前に、LoggingAspectのlogBefore()メソッドが実行され、メソッド名がログ出力されます。
AOPのメリット
- クロスカッティングコンセルンの関心事分離が可能
- 新しい関心事の追加が容易
- コードの重複排除につながる
デメリット
- AOPによるコードの振る舞いが複雑化するため、理解が難しくなる
- AOPとオブジェクト指向の設計思想との親和性が低い
AOPはモジュール化できる関心事がはっきりしており、横断的な処理がクリアな場合に有効です。一方で過剰なAOPの利用は複雑性を増すため、要件に応じて使い分ける必要があります。Spring FrameworkはAOPを適用しやすい環境を提供しているため、有効に活用することが重要です。