S2GroovyBuilderでClosureを使う

adviceにClosureを渡せるところがすてきだと思う。

こんなことをしてみた。

    • Container全体でTraceInterceptorを使うかどうかのコントロール
    • Container全体でDEBUG用のロジックを使うかどうかのコントロール
    • 上記二つの条件分岐により設定情報が見にくくならないようにメソッド使う。

CalcClient

package taedium.study;

import org.seasar.framework.container.S2Container;
import org.seasar.framework.container.factory.S2ContainerFactory;
import test.org.seasar.extension.openamf.Calculator;

public class CalcClient {

    private static final String PATH =
        "taedium/study/CalcClient.groovy";
        
    public static void main(String[] args) {
        S2Container container = S2ContainerFactory.create(PATH);
        Calculator calc = (Calculator) container.getComponent(Calculator.class);
        int answer = calc.plus(10,20);
        System.out.println(answer);
    }
}

クラスに属さないメソッドの定義(defを使ったもの)の中からはそのスコープの外で定義された変数を参照できないのでメソッドからDEBUGやTRACEを参照するためにクラスをつくる。
CalcClient.groovy

import org.seasar.framework.aop.interceptors.*
import org.seasar.groovy.*
import test.org.seasar.extension.openamf.CalculatorImpl

// Container
new SeasarBuilder().components(){
    ad = new Advices(); // 下で定義したclass
    include("j2ee.dicon")
    component(class: TraceInterceptor, name: "trace")
    component(class: CalculatorImpl){
        aspect(advice: "j2ee.requiredTx")
        aspect(advice: ad.trace())
        aspect(advice: ad.intercept())
    }
}


class Advices { 
    TRACE = true
    DEBUG = true
    
    /* DefaultのClosure、interceptされてるmethodを実行するだけ */
    invocation = { return it.proceed() }
            
    /*
     * TRACEがtrueならばTraceInterceptorのComponent登録名(String)を返す
     * TRACEがfalseならばDefaultのClosureを返す
     */
    Object trace() {
        if (TRACE) {
            return "trace"
        }        
        return invocation
    }
    
     /*
      * DEBUGがtrueならば任意のClosureを返す
      * DEBUGがfalseならばDefaultのClosureを返す
      */    
      Object intercept() {
        if (DEBUG) {
            return { return 9999999 }
        }        
        return invocation
    }
}

実行結果(TRACEもDEBUGもtrueの場合)

BEGIN est.org.seasar.extension.openamf.CalculatorImpl#plus(10, 20)
END est.org.seasar.extension.openamf.CalculatorImpl#plus(10, 20) : 9999999
9999999

実行結果(TRACEもDEBUGもfalseの場合)

30

ひさびさにSeasarさわった。
diconからgroovyをincludeできることとその逆ができることを確認。適材適所で使い分けができますね。