SpringのAOPはAspectJとは似て非なり

火曜日。今日は朝から調子が良かったb休日明けの月曜日は特異日だね(涙)

昨日の続き。LogicBean#executeと、HogeAccessObject#executeは、

    // 本来するべき処理

のみとなる。これは使える!みたいなんだけど・・・推定無罪なSpringのAOPの悲しいお知らせ。

SpringのAOPで共通的な処理を織り込もうとすると、プロキシなクラスを介す。
絵に描くとこんな感じか。

         +-------------------------+
         |proxy                    |
(*)----->|----->LogicBean#execute  |
         |                         |
         +-------------------------+     (*):織り込みたい共通処理

織り込みたい共通的な処理は、よくWebで紹介さえているメソッド開始/終了のトレースログ出力処理とか。Google先生に聞いてみるだけでも、こんなにも、
google:Spring AOP ログ処理
全てかどうかは不明だが、約 69,100 件 (0.13 秒) 。

ここで疑問が生じた。プロキシを介してしか織り込めないのだとしたら、自クラスから呼び出す自クラス内のメソッドへは織り込むことができないのか?ということで実験実験・・・

public class LogicBean {
    public void execute() {
        if (true) {
            this.hoge();
        }
    }
    public void hoge() {
    }
}

このクラスのすべてのメソッド(execute、hoge)へトレースログ出力処理を織り込むとする。以下設定例。

<aop:config>
  <aop:pointcut id="pointcut-trace" expression="execution(* *(..))" />
  <aop:advisor advice-ref="traceAdvice" pointcut-ref="pointcut-trace" />
</aop:config>

AOPの共通処理には、MethodInterceptorを実装して、System.out.printlnを織り込む。

import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;

public class LoggingAdvice implements MethodInterceptor {
    public Object invoke(MethodInvocation invocation) throws Throwable {
        String methodName = invocation.getMethod().getName();

        System.out.println("[LOG] Advice METHOD: " + methodName + " is calling.");  // トレース出力
        Object rtnObj = invocation.proceed(); // LogicBeanのメソッド呼び出し
        System.out.println("[LOG] Advice METHOD: " + methodName + " was called.");  // トレース出力
        return rtnObj;
    }
}

さて結果は・・・

[LOG] Advice METHOD: execute is calling.
[LOG] Advice METHOD: execute was called.

hoge()のトレースが出力されないね・・・あぁ無情・・・(涙)
AspectJを使うっきゃないらしい?