-S16: 家に帰ろう

以前、<initMethod>によってコンポーネント初期化をメソッドによって行う方法を解説しましたが、Seasar2にはコンポーネントのライフサイクル管理としてコンポーネントの破棄時にイベント的に呼び出されるメソッドを指定することができます。

list16-1. 終了時処理があるGoBackCar.java
package tutorial.org.seasar.console;
import java.text.SimpleDateFormat;
import java.util.Date;
public class GoHomeCar implements Car {
  public void run() {
    System.out.println("Shopping!");
  }
  public void comeBack(Date back) {
    SimpleDateFormat fmt = new SimpleDateFormat("HH:mm");
    System.out.println("I have come back at " + fmt.format(back));
  }
}

list16-1ではインターフェイスCarの定義メソッドrun()に加え、任意に追加したメソッドcomeBack(Date)があります。

list16-2. destroyMethodを指定したcar.xml修正版
<?xml version="1.0" encoding="UTF-8"?>
<components>
  <component class="tutorial.org.seasar.console.GoHomeCar">
    <destroyMethod name="comeBack">
      <arg>new java.util.Date()</arg>
    </destroyMethod>
    <destroyMethod>out.println('I am tired, fuu.')</destroyMethod>
  </component>
</components>

list16-2では二つの<destroyMethod>が記述されています。

list16-3. Highway.javaの修正
package tutorial.org.seasar.console;
import org.seasar.framework.container.S2Container;
import org.seasar.framework.container.factory.S2ContainerFactory;
public class Highway {
  private static String PATH = "tutorial/org/seasar/console/car.xml";
  public static void main(String[] args) {
    S2Container container = S2ContainerFactory.create(PATH);
    Car car = (Car)container.getComponent(Car.class);
    car.run();
    container.destroy();
  }
}

list16-4では大本のHighwayクラスを修正しています。S2Container#destroy()メソッドを呼び出すことによって、コンテナに登録されているコンポーネントのすべての終了化メソッドが呼び出されます。S2Container#destroy()メソッドを呼び出すことは必須ではありませんが、これまでのように呼び出さないと、設定XMLに<destroyMethod>エレメントを記述しても無意味です。また、S2Container#destroy()メソッドは、この終了化処理以外のことはしません。サンプルを実行すると、

Shopping!
I have come back at 18:12
I am tired, fuu.

一行目がGoHomeCar#run()の結果、二行目が<destroyMethod>エレメントにより呼び出されたGoBackCar#comeBack(Date)メソッドの結果で、最後が<destroyMethod>エレメント中に直接書いたSelの実行結果です。<destroyMethod>エレメントは<initMethod>エレメントと同様に、任意のname属性を持ち、値にメソッド名を指定します。その場合は、任意数の<arg>エレメントを引数リストとして指定のメソッドを呼び出します。name属性が無い場合、エレメントボディに記述されたSelを実行します。
<destroyMethod>エレメントの動作要件は以下のとおりです。

  • <component>エレメントにinstance属性を記述しないか記述値を"singleton"とする
  • <destroyMethod>エレメントを記述する
  • S2Container#destroy()メソッドを呼び出す

後の二つの要件は先の説明のとおりです。一番はじめの<component>エレメントのinstance属性は、記述しないとデフォルトの"singleton"が適用されます。instance属性が取りえる値は、"singleton" "prototype" "outer" ですが、"singleton"以外では終了化メソッドが呼び出されません。
このinstance属性の"singleton"と"prototype"の違いについては次回に解説します。"outer"はさらにその次の回に取り上げます。