ICEfacesのライフサイクル

今回はICEfacesのライフサイクルについて軽くみてみる。

ICEfacesはステートフルなアプリを想定しているので、設定としてはデフォルト値であるcom.icesoft.faces.standardRequestScopeはfalseのままにしてある。実際falseだとアプリは作りやすい。

今回もテストが容易なNetBeansを使用してあるが、特に依存した話ではないので気にせずに。


VisualWebでは「AbstractPageBean」を継承したページBeanをJSPと1:1に作成する。これはユーザーが良く行うようなメソッド等を呼び出しやすくしているもので、特に苦労することはない。最初から用意されているので便利なのが、各フェーズごとにメソッドが用意されている。

順番に

  • init
  • preprocess
  • prerender
  • destroy

となっている。JSFのライフサイクルを理解しているのならそれぞれがどのあたりで実行されるのかだいたいわかるはず。大まかに説明すると

  • init 初期設定
  • preprocess ボタンが押されたときなどアクションメソッドが呼ばれる直前
  • prerender レンダリング直前
  • destroy 破棄時

となっている。preprocessはGETなどの初回表示には呼ばれないのに注意だ。

ちなみに「beforeInvokeApplication」とかいうさらにJSFのコアを知っている人ならすぐわかりそうなメソッドも用意されていて、それらも順番に自動的に呼ばれるようになっている。


ここまでは通常のJSFのお話。ページBeanはrequestスコープで順番に呼ばれるだけだ。ただ、ポストバックのときのみ「preprocessメソッド」が呼ばれるというのに注意したい。


続いてICEfacesでのテスト。


まず各種メソッドが呼ばれたら出力するようにソースを作る。


Page1.java。ログ出力以外は省略

public Page1() {
    System.out.println("Page1:コンストラクタ");
}

public void init() {
    System.out.println("Page1:init");

}
public void preprocess() {
    System.out.println("Page1:preprocess");

}
public void prerender() {
    System.out.println("Page1:prerender");

}
public void destroy() {
    System.out.println("Page1:destroy");

}
    

今回はPage2も作成してお互いに行き来が出来るようにナビゲーションを作成しておく。



実行!


初期表示されたときのログは以下のとおり。

Page1:コンストラクタ
Page1:init
Page1:prerender
Page1:destroy

たぶん、予想通りだと思う。



続いてボタンクリックなど何らかのアクションを起こす。

Page1:preprocess
Page1:prerender

このときはinitとdestroyが呼ばれていない。かわりにpreprocessが呼ばれている。



今度はPage2へ遷移するアクションを起こす。

Page1:preprocess
Page2:コンストラクタ
Page2:init
Page2:prerender
Page2:destroy

これも予想通りだと思う。



続いてPage1へ戻るアクションを起こす。

Page2:preprocess
Page1:init
Page1:prerender

ポイントはinitメソッドがまた呼ばれたこと。そしてdestroyは呼ばれていないこと。



もう一度念のためにpage2へ移動してみる。

Page1:preprocess
Page2:init
Page2:prerender

ふむ。


今度はブラウザの再表示ボタンを押してみる。

Page2:prerender

ふむふむ。



まとめてみる

  • コンストラクタは初回表示のみ呼ばれる
  • initは初回表示と画面遷移時に呼ばれる
  • preprocessはなんらかのアクションがあったときのみ呼ばれる
  • prerenderはいかなるときも呼ばれる(ただし、遷移先があれば遷移先のみ)
  • destroyは初回表示の1回だけ最後に呼ばれる。コンストラクタと同じリクエストのときのみ


以上のことから

  • コンストラクタはセッションが維持される限り1度のみ
  • initの初期化タイミングは画面単位と考えると非常にわかりやすい。画面毎に必要な1度きりの初期化(各種ドロップダウンリストとかの準備等)はここで問題なし。JSFより非常にやりやすいかと。F5連打されても呼ばれないのはメリット。
  • destroyは利用しないほうがよさそう。