AnnotationValidationInterceptorとAspectJ

GWボケがいまだ抜けないまま、相変わらずの仕事なさでStruts2いぢりを再開。
今回はAspectJアノテーションを使ってAOPをしてみる。

aspectの定義とか

XMLにPointcutやAdviceの定義はしないでアノテーションでやってみる。

Aspectを定義するクラスを作成する。
@Aspect
public class TraceLogger {
    private static final Logger logger = Logger.getLogger(TraceLogger.class);
    
    @Pointcut("execution(* *..*Action.*(..))")
    public void tracePointCut() {}
    
    @Around("tracePointCut()")
    public Object trace(ProceedingJoinPoint pjp) throws Throwable {
        Object retVal;
        logger.debug("trace start:" + pjp.getTarget());
        retVal = pjp.proceed();
        logger.debug("trace end  :" + pjp.getTarget());
        return retVal;
    }
}

適当にトレースログを出すてことで。

Around以外にもBeforeとかあるけどサンプルだし。
Pointcutの指定を@Around("ここに指定")へ直接書いてもOK。
わざわざ@Pointcutで定義するのは複数の箇所で同じAdviceを適用するときに便利になるため、らしい。

最低限必要なXML定義

applicationContext.xmlに以下を追加

  <aop:aspectj-autoproxy />

  <bean id="traceLogger" class="struts2.sample.aop.TraceLogger" />

autoproxyの追加だけじゃ起動時にアノテーションみて追加してくれないのね。
なんで動いてくれないんだろってじつははまった…orz
component-scanでBLやらDAOはアノテーションつけてればロードしてくれるのにね。

いざ実行

が、動かない。
Daoパッケージにも仕込んであったんだけど、こっちは動いたのにActionに仕込んだほうは例外が発生してだめぽ。
例外をあげてるのが「AnnotationValidationInterceptor」。
バリデーションチェックを実行するかリフレクション使って(インターセプトした)アクションクラスのメソッドを取得するところでNoSuchMethodExceptionに。
ここにわたってくるActionクラスがAopProxyになってるらしくて呼び出せないみたい。
どうしたものかとSpring側のクラスをみるとJdkDynamicAopProxyのメンバAdvicedSupportが実参照の情報を持ってるみたいなんだけど…外からアクセスできないorz

結論

なんかめんどくさそうなので取り合えず放置。
Actionに対してAOPを適用させないか、させるのならStruts2のInterceptorを実装してこっちでやるかってところかも。
(たぶん)AOPをActionにかけてるとほかのInterceptorでも同様の例外が出る気がするし。


んー、境界面はきっちり分かれるけどなんか気持ち悪いなぁ。
同じAdviceを適用させたい場合とか。