Revision 4 as of 2009-12-16 04:59:24

Clear message
Locked History Actions

guice/Wicket/GuiceFilter

GuiceFilterの利用

サーブレットフィルタとしてGuiceFilterを用いると、@SessionScopedや@RequestScopedのアノテーションが有効になる。 それらのスコープの制御は、Guiceがサーブレットからのリクエストをフックして行うからである。

Wicketでこの機能を利用するには、基本的には「サーブレット」に記述した通りのことを行えばよい。 ただし、これをやっても「インジェクションの方法」で取り上げた問題が解決するわけではない。 相変わらず以下の問題があるのでまとめておく。

  • コンストラクタ注入されるオブジェクト以外はコンストラクタ中で使用することはできないが、一般にWicketのページクラスにはそのような特別なパラメータを指定できる余地がない。
  • フィールド注入したとしても、Wicketのページは直列化されるため、それらのオブジェクトはSerizlizableでなければならず、大きいと直列化領域を圧迫する。なおかつ、直列化復帰後に(DB接続等の)機能を復旧できなければならない。

したがって、少なくともWicketのページ及びその中のコンポーネント等では、DIではなくサービスロケータを使用するのがベストであると結論づけた。

その上で、@SessionScoped/@RequestScopedの恩恵にあずかることはできる。 サービスロケータからこれらのオブジェクトを取得すると、それぞれセッションで一意なオブジェクト、リクエストで一意なオブジェクトを取得することができるのである。

そしてむしろ、これらのスコープされたオブジェクトを使う場合にはオブジェクトそのものの注入は避けるべきである。 なぜなら、注入先のオブジェクトがリクエストやセッションを越えて生き残る場合には、誤ってそのスコープ外でスコープされたオブジェクトを使ってしまうというバグになりかねないからである。

したがって、これらのスコープされたオブジェクト使う場合は、必ずプロバイダあるいはサービスロケータから取得するのがベストと思われる。

Guice, Wicket, Jettyを使う例

以下では、Guice 2.0, Wicket 1.4.3, Jetty 7.0.1を利用している。 特にJettyはバージョンによって仕様がよく変更されているので注意・

Guiceは極力XMLを排除するように設計されている。ウェブとサーブレットでのGuiceFilterの利用例でもこれが貫かれている。 それでも他のサーブレットコンテナでは最低限のweb.xml記述が必要と思われるが、 Jettyでは完全にweb.xmlを排除することができる。

ほとんどのセットアップはInjectorの作成時に行えばよい。 仮にInjectorが得られたものとして、以下のコードでJettyを起動する。 以下のコードは、ほぼどんな場合でも同じになると思われる。 {{{

}}} 次に、Injectorの生成について見てみるが、その前にWicketFilterのサブクラスを作成し、 @Singletonを指定しておく。

import org.apache.wicket.protocol.http.*;

import com.google.inject.*;

@Singleton
public class MyWicketFilter extends WicketFilter {
}