S2GroovyBuilder

##### ドキュメント

- 概要
- クイックスタート
- ヒント
- 文法
- ダウンロード

##### Project Documentation

- About S2GroovyBuilder
- Project Info
- Project Reports
- Development Process

## S2Container

### S2Containerを作成する

SeasarBuilderクラスのインスタンスを作成し、 SeasarBuilder#container() もしくは SeasarBuilder#components() を呼ぶことでS2Containerを作成することができます。

    builder   = new SeasarBuilder()
    container = builder.container()
    container = builder.components() // builder.container()と同じ

### 名前空間を設定する

S2Containerの名前空間を指定するにはcontainerの引数に名前空間を示す文字列を渡します。 下の例ではnamespaceという名前空間でS2Containerを作成しています。

    builder   = new SeasarBuilder()
    container = builder.container("namespace")

コンテナー同士は親子関係を持つことができます。 この機能はS2Containerで定義されているものですが、 GroovyはJavaとシームレスに接続されていますので、groovy-seasarから簡単に利用できます。

    builder = new SeasarBuilder()
    parent = builder.container("parent")
    child  = builder.container("child")
    parent.include(child)

## コンポーネント

### コンポーネントを登録する

S2Container#container()メソッドのクロージャ内で component()メソッドを呼び出すことによって、 S2Containerにコンポーネントを登録することができます。

    import java.math.BigDecimal
    import java.util.ArrayList
    import java.util.HashMap
    import org.seasar.groovy.SeasarBuilder

    new SeasarBuilder().container(){
        // クラスを登録
        component(ArrayList)
        // クラスを名前付きで登録
        component(class: HashMap, name: "hash")
        // オブジェクトを登録
        component(new Object())
        // オブジェクトを名前付きで登録
        component(obj: new BigDecimal('1'), name: 'decimal')
    }

### コンストラクタの設定

コンポーネントのコンストラクタに対して、 引数を渡したい場合はcomponentメソッドのクロージャ内でargメソッドを呼び出してください。 argメソッドはrefという名前付きパラメータとともに呼び出すことで、 既にコンテナーに登録されているコンポーネントの参照を引数として利用することができます。

    component(class: Integer, name: "one") {
        arg(1)
    }
    component(class: Integer, name: "oneWithRef") {
        arg(ref: "one")
    }

### プロパティを利用した値の設定

コンポーネントに対して、プロパティを利用して値を設定することができます。 componentメソッドのクロージャのなかでpropメソッドを呼びだします。

直接、値を設定する場合は名前付きパラメータのvalueで指定します。

    component(java.util.Date) {
        prop(name:"time", value:0)
    }

既にコンテナーに登録されたコンポーネントを参照することもできます。 refパラメータにコンポーネント名を渡します。

    component(class:Integer, name:"zero") {
        arg(0)
    }
    component(class:java.util.Date) {
        prop(name:"time", ref:"zero")
    }

## ライフサイクル

コンテナに登録されたコンポーネントに対して、 コンテナの初期化時、終了時にメソッドの呼び出しを行なうことができます。

### 初期化メソッドの呼び出し

コンテナの初期化時にコンポーネントのメソッドを呼び出したい場合は component()のクロージャ内でinit()を呼び出します。 init()のクロージャ内でarg()メソッドを呼び出すことによって、 コンポーネントに引数を渡すことができます。

    component(java.util.HashMap){
        init("put"){ arg("key"); arg("value") }
    }

### 終了時メソッドの呼び出し

コンテナの終了時にメソッド呼び出しを行いたい場合も、 初期化メソッドの呼び出しのかわりにdestroy()を利用します。

    component(Connection){
        destroy("close")
    }

## AOPの適用

### 参照によるAOPの適用

componentメソッドのクロージャ内でaspectメソッドを呼ぶことによって、 componentに対してアドバイスを適用することができます。 aspectメソッドは名前付きパラメータをとり、 適用するアドバイスとポイントカットとを指定できます。

    new SeasarBuilder().container{
        component(class:TraceInterceptor, name:"traceInterceptor")
        component(java.util.Date) {
            arg(0)
            aspect(pointcut:"getTime, hashCode", advice:"traceInterceptor")
        }
        component(java.util.ArrayList) {
            aspect(advice:"traceInterceptor")
        }
        component(AspectTarget){
        	aspect(pointcut:"run", advice: {joinpoint|
        		println "before run"
        		joinpoint.proceed()
        		println "after run"
        	})
        }
    }

### クロージャによるAOPの適用

アドバイスをクロージャを利用して直接記述することができます。 クロージャの引数としてMethodInvocationが渡されますので、 そこにアドバイスをGroovyで書くことができます。 クロージャの戻り値がそのMethodInterceptorの戻り値となりますので、 もし意味のある値を返したい場合は、その値を返す必要があります。

    component(AspectTarget){
        closure = {invocation|
            println "before run"
            invocation.proceed()
            println "after run"
        }
        aspect(pointcut:"run", advice:closure)
    }