ICEFacesでS2JDBCを使う その2
こんなご意見をいただきました。
http://d.hatena.ne.jp/shin/20090423/p2
これは僕も気にはなっていたものの、とりあえず目をつぶっていた問題です。最初はSeasarではステートレスのコンポーネントを管理して、ステートフルなJSFのコンポーネントにインジェクションするということを考えていたのですが、やり方がよく分からなかったので、仕方なくこうしていました。で、せっかくの機会なので別のやり方を考えてみました。
Seasarは外部のコンポーネントにインジェクションすることもできることに気付いたので、今回はその方法で行きます。
DelegatingVariableResolverを使うところまでは同じですが、基本的にfaces-config.xmlの設定からコンポーネントを取得するようにします。
public Object resolveVariable(FacesContext facesContext, String name) throws EvaluationException { Object value = resolveOriginal(facesContext, name); if (value != null) { S2Container s2con = SingletonS2ContainerFactory.getContainer(); if (s2con != null && s2con.hasComponentDef(value.getClass())) { s2con.injectDependency(value); } } return value; }
取得後、Seasarにコンポーネント定義があるかを判別し、あるようならインジェクションさせます。
ここで、外部のコンポーネントにインジェクションする場合はdiconファイルにもそのように設定する必要があります。
<component name="Page1" class="webapplication1.Page1" instance="outer"/>
instance="outer"という設定がそれにあたります。
これで以上です。前回使ったS2ContainerFilterは今回は使いません。これで一応は動作しました。
しかし、Pageクラスが描画されるまでにresolveVariableが2回呼び出されることに気付きました。呼ばれる都度、インジェクションが走ることになるわけです。うーん、レスポンス的にいかがなものか・・・?おそらく問題になることは少ないとは思うのですが、それはそれで気持ちが悪い。かといって、インジェクション済みのフラグを持たせるのはもっと気持ち悪い。それをするくらいなら、Pageクラスに直接Seasarのコードを埋め込む方がマシですね。
ということで、なかなかすっきりしなかったりします。とりあえず、また別の方法を思いついたらトライします。