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") }
}

init()にはOGNLの式を渡すこともできます。

component(HelloBean){
    init(ognl:"#self.message = 'Hello, OGNL!'")
}

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

コンテナの終了時にメソッド呼び出しを行いたい場合も、 初期化メソッドの呼び出しのかわりに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)
}