-S08: BGMを聴く

三番目のコンポーネント設定方法である、初期化メソッドを用いた設定を行います。これはSeasar2にユニークな設定方法です。

list08-1. 初期化メソッドを持つStereoCar.java
package tutorial.org.seasar.console;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class StereoCar implements Car {
  private List list = new ArrayList();

  public void addBGM(BGM bgm) {
    list.add(bgm);
  }

  public void run() {
    StringBuffer buffer = new StringBuffer();
    for(Iterator it = list.iterator(); it.hasNext();) {
      BGM bgm = (BGM)it.next();
      buffer.append(bgm.getDisplay());
      buffer.append(", ");
    }
    System.out.println(buffer.toString());
  }
}

list08-1のStereoCarクラスは、BGMをリスト登録するaddBGM(BGM)メソッドがあります。引数のBGMオブジェクトをクラスメンバのリストに追加していきます。

list08-2. メソッドの引数に渡すサンプルオブジェクトBGM.javaとCD.java
package tutorial.org.seasar.console;
public interface BGM {
  public String getDisplay();
}

package tutorial.org.seasar.console;
public class CD implements BGM {
  private String artist;
  private String title;
  public CD(String artist, String title) {
    this.artist = artist;
    this.title = title;
  }
  public String getDisplay() {
    return artist + "'s [" + title + "]"; 
  }
}

list08-2は、addBGM(BGM)メソッドの引数となるインターフェイスと実装クラスです。実装のCDクラスはコンストラクタで設定されたアーチスト名とアルバムタイトルを保持し、getDisplay() メソッドで情報を文字列として返すように作ってます。

list08-3. 初期化メソッドを利用するcar.xml修正版
<?xml version="1.0" encoding="UTF-8"?>
<components>
  <component class="tutorial.org.seasar.console.StereoCar">
    <initMethod name="addBGM">
      <arg>
        <component class="tutorial.org.seasar.console.CD">
          <arg>'Spitz'</arg>
          <arg>'Iroirokoromo'</arg>
        </component>
      </arg>
    </initMethod>
    <initMethod name="addBGM">
      <arg>antenna</arg>
    </initMethod>
  </component>

  <component name="antenna" class="tutorial.org.seasar.console.CD">
    <arg>'Qururi'</arg>
    <arg>'Antenna'</arg>
  </component>
</components>

初期化メソッドを利用するためには、<component>エレメントの子要素として<initMethod>エレメントを追加します。<initMethod>エレメントは必須のname属性を持ち、値に初期化メソッド名を記述します。list08-3では"addBGM"メソッドを設定しています。初期化メソッドの引数の数にあわせて、<arg>エレメントを記述します。コンストラクタの例と同じで、出現順序に従ってメソッド引数に適応されます。"addBGM(BGM)"メソッドは引数を一つしか撮りませんから、<initMethod>エレメント毎に<arg>エレメントが一つづつ記述されています。
<initMethod>エレメントはname属性の異同に関わらず、一つの</component>エレメントあたり複数記述することができ、エレメント毎の設定でメソッドコールが行われます。list08-3では<initMethod>エレメントが二つ記述されていますので、二回初期化メソッドがコールされることになります。
実行すると以下のとおりの結果が表示されます。

Spitz's [Iroirokoromo], Qururi's [Antenna],

ところで、list08-3のはじめの<initMethod>エレメントでは、<arg>エレメントの中でさらに<component>エレメントによるコンポーネント定義を行っています。これは便利な方法で、コンストラクタを利用する場合でも同様に使える方法です。また、次の<initMethod>エレメントでは、<arg>エレメントボディで"antenna"と記述されています。これはSelによって別途定義された名前付きコンポーネントへの参照と判断され、"addBGM(BGM)"メソッドの引数に"anntena"コンポーネントが引き渡されます。