Springにおけるアスペクト指向プログラミングの実践的な利用方法

アスペクト指向プログラミング(AOP)は、横断的関心事をモジュール化するためのプログラミングパラダイムです。本記事では、Spring FrameworkにおけるAOPの具体的な実装方法について解説します。

基本的なログ出力の実装

以下の例では、特定のメソッド実行時に自動的にログを出力するアスペクトを実装しています。


package com.example.logging;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;

@Component
@Aspect
public class LoggingAspect {
    
    @Before("execution(* com.example.service.UserService.processUser(..))")
    public void logMethodStart(JoinPoint joinPoint) {
        System.out.println("メソッド開始: " + joinPoint.getSignature().getName());
    }
    
    @After("execution(* com.example.service.UserService.processUser(..))")
    public void logMethodEnd(JoinPoint joinPoint) {
        System.out.println("メソッド終了: " + joinPoint.getSignature().getName());
    }
}

ポイントカットの再利用

共通の実行ポイントを再利用するためには、@Pointcutアノテーションを使用します。


@Pointcut("execution(* com.example.service.UserService.processUser(..))")
public void userProcessing() {}

@Before("userProcessing()")
public void beforeProcessing(JoinPoint joinPoint) {
    System.out.println("前処理: " + joinPoint.getSignature().getName());
}

@After("userProcessing()")
public void afterProcessing(JoinPoint joinPoint) {
    System.out.println("後処理: " + joinPoint.getSignature().getName());
}

アラウンドアドバイスの実装

@Aroundアノテーションを使用すると、メソッド実行前後のすべての処理を1つにまとめることができます。


@Around("userProcessing()")
public Object aroundProcessing(ProceedingJoinPoint joinPoint) throws Throwable {
    System.out.println("メソッド開始前処理");
    
    try {
        Object result = joinPoint.proceed();
        System.out.println("メソッド正常終了");
        return result;
    } catch (Exception e) {
        System.out.println("例外発生: " + e.getMessage());
        throw e;
    } finally {
        System.out.println("共通後処理");
    }
}

設定方法

Springの設定ファイルに以下の構成を追加してください。


<aop:aspectj-autoproxy/>

実行結果の例

メソッド開始前処理
前処理: processUser
メソッド本体実行
メソッド正常終了
共通後処理
後処理: processUser

アドバイスの優先順位

  • @Aroundで定義した処理が最も優先度が高い
  • 通常のアドバイス(@Before, @After等)は、アラウンドアドバイスの前後に実行される
  • 複数のアスペクトがある場合は、@Orderアノテーションで実行順を明示的に指定する

タグ: Spring Framework アスペクト指向プログラミング ロギング 依存性注入 Java

6月20日 18:33 投稿