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クラスでしか対応していません.
さてさて・・・このままではまずいですよ・・・