Apache Shale ViewController その3

ViewControllerは,Apache Shale 1.0.3からRequest Scopeにおく必要があります.
Request Scopeに置かないと,init()やら,prerender()のような,コールバックメソッドを呼んでくれなくなりました.

このあたりが,大きな変更と言えます.

その代わりと言ってはなんですが,新たに各スコープに対応したバッキングビーンラッパーが用意されました.

アプリケーションスコープ

org.apache.shale.view.AbstractApplicationBeanを継承します.

AbstractApplicationBeanには,以下のコールバックメソッドが用意されています.

  • init()

インスタンス生成後,バッキングビーンの呼び出し時に呼ばれます.バッキングビーンは,アプリケーションスコープに置かれるので,当然init()は1度呼び出されたら,2度呼び出されることはありません.

  • destroy()

アプリケーションの削除時,又はアプリケーションを終了したときに呼ばれます.

セッションスコープ

org.apache.shale.view.AbstractSessionBeanを継承します.

AbstractSessionBeanには,以下のコールバックメソッドが用意されています.

  • init()

インスタンス生成後,バッキングビーンの呼び出し時に呼ばれます.バッキングビーンは,セッションスコープに置かれるため,セッション毎に1回呼び出されます.

  • passivate()

Sessionが非活性化されたときに呼ばれます.

  • activate()

Sessionが活性化されたときに呼ばれます.

  • destroy()

セッションの破棄時に呼ばれます.

リクエストスコープ

org.apache.shale.view.AbstractRequestBeanを継承します.

AbstractRequestBeanには,以下のコールバックメソッドが用意されています.

  • init()

インスタンス生成後,バッキングビーンの呼び出し時に呼ばれます.バッキングビーンはリクエストスコープに保持されるため,リクエスト毎にinit()は呼ばれます.

  • destroy()

バッキングビーンの破棄時に呼ばれます.画面にレスポンスを返した後ってところですかね.

しかし,ViewControllerクラスがあるのに,さらにAbstractRequestBeanなんて作る意味があるんでしょうか?使い道もないし.

各スコープ毎のバッキングビーンには,AbstractFacesBeanが継承されているため,便利なヘルパーメソッドが使えるようになっています.

感想

なんだか,苦し紛れの対応のような気がしました.
まず,各バッキングビーンをどのスコープに置くかは,faces-config.xmlで定義します.それだけでなく,バッキングビーン側にまでスコープに対応したビーンを継承させるのは複雑さが増すし,手間がかかります.

AbstractRequestBeanなんて,ほとんどおまけみたいなもので,作成する必要すら感じません.

これらの対応は結局のところ,init()とdestroy()のタイミングを思うようにできず,仕方がなくこのような形になってしまったと思われます.

これらのコールバックメソッドを呼んでいる場所は,
org.apache.shale.view.faces.LifecycleListenerクラスです.このクラスは

  • ServletContextAttributeListener
  • ServletContextListener
  • HttpSessionActivationListener
  • HttpSessionAttributeListener
  • HttpSessionListener
  • ServletRequestAttributeListener
  • ServletRequestListener

をimplementsしており,それぞれのコールバックはリスナーによって呼ばれます.


それぞれのスコープに対応したコールバックにきっと見覚えがあることでしょう.
しかし,一時しのぎの対応かと思っていたらこのまま1.0.3としてリリースされてしまいました.

確かに,すべてを対応させる為にはこれしかないように思いますが・・・他に手はないのだろうか・・・

AbstractSessionBeanのpassivate()やactivate()の必要性もないし,init()とdestroy()を呼びたいだけなのだから,すべてViewControllerクラスでできるようにするべきだと思います.

一番使いたいコールバックであるprerender()メソッドもViewControllerクラスを継承してさらにリクエストスコープでしか扱えないのも問題があります.postbackにしてもviewControllerクラスでしか対応していません.

さてさて・・・このままではまずいですよ・・・