Wicket + Spring 連携
これまで Wicket メーリングリストなどで何度も連携の方式について議論されてきましたが、以下の 2 点がネックとなりエレガントな方法での連携が難しいとされてきました。
- コンポーネントがセッションに保存されること
- コンポーネントの生成が管理されていないこと
コンポーネントにそのまま注入してしまうと、注入されたクラスもセッションに保存されるため Serializable でなければいけなくなってしまいます。
また Wicket アプリケーションではコードのどこででも new を使ってコンポーネントを生成できます。コンストラクタの引数で ID やモデルその他を渡すスタイルが Wicket の特長であるので、Spring の流儀 (生成を Spring に任せる) とは相容れません。
これらを解消しつつ連携するためのクラス群が wicket-spring プロジェクトにて提供されています。 wicket-spring プロジェクトでは下記 2 つの連携方法をサポートします。
- リソースロケータ
- プロキシ
リソースロケータ
必要なときにコンポーネント側から bean をルックアップする方法です。自分で実装しても簡単ですが、wicket-spring でクラスが提供されています。
使い方
web.xml
Spring の ApplicationContext を生成するために ContextLoaderListener を登録します。
<listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener>WicketServlet に WebApplication ファクトリとして SpringWebApplicatoinFactory を登録します。
<servlet>
<servlet-name>wicket</servlet-name>
<servlet-class>wicket.protocol.http.WicketServlet</servlet-class>
<init-param>
<param-name>applicationFactoryClassName</param-name>
<param-value>wicket.contrib.spring.SpringWebApplicationFactory</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
applicationContext.xml
WebApplication のサブクラスを登録します。上で登録した SpringWebApplicationFactory は ApplicationContext から WebApplication のサブクラスをルックアップします。id は何でも構いません。
<bean id="wicketApplication" class="project.MyApplication"> <property name="contactDao" ref="contactDao"/> </bean>この段階で bean "wicketApplication" は依存性の注入対象ですので、あとは好きにプロパティを持たせていけば Spring が依存性を解決してくれます。以下は Page から DAO を参照する例です。
WebApplication のサブクラス
プロパティとして DAO を持たせます。
class MyApplication extends WebApplication {
private ContactDao dao;
public void setContactDao(ContactDao dao) { this.dao=dao; }
public ContactDao getContactDao() { return dao; }
}
Page のベースクラス
DAO を取得するメソッドを用意します。
class BasePage extends WebPage {
ContactDao getContactDao() {
return ((MyApplication)getApplication).getContactDao();
}
}
Page
必要なときに getContactDao() を呼び出して DAO を取得して使用します。DAO インスタンスへの参照は一時変数として利用するだけなのでセッションに保存されることはありません。
class EditContact extends WebPage {
public EditContact(long id) {
Form form=new Form("form",...) {
public void onSubmit() {
Contact contact=getContact();
…
getContactDao().save(contact); // ここで取得
…
}
}
}
}
プロキシ
上記リソースロケータの方法はシンプルで良いのですが WebApplication が全ての依存性を持ってしまうことが難点です。またできればルックアップではなく依存性を注入してもらう形で利用したいところです。
そこでプロキシの方法では、依存オブジェクトの呼び出しをインターセプトして内部的にルックアップすることで、ユーザアプリケーションから透過的に呼び出しが行えるようになっています。
使い方
使い方はとても簡単です。
- WebApplication は wicket.spring.injection.annot.AnnotSpringWebApplication を継承しておく
- Page クラスの依存性を注入する対象にアノテーションをつける
アノテーション
Page クラスでは依存性を注入してもらいたいインスタンス変数をアノテーションをつけます。
class EditContact extends InjectableWebPage {
@SpringBean
private ContactDao dao;
@SpringBean(name="userDao") private UserDao userDao;
public EditContact(long userId) {
…
}
}
引数なしの @SpringBean は ApplicationContext を変数の型 (例だと ContactDao とか UserDao) でルックアップします。同じ型の bean が複数ある場合には特定できるように name 属性を指定します。内部的には @SpringBean で指定した変数にプロキシが割り当てられ、変数利用のたびにそのプロキシが必要に応じてルックアップします。bean 自体がシリアライズされることはありません。
ダウンロード方法
2006/02/07 のスナップショットからパッケージが配布されるようになりました。 wicket-spring-cattr, wicket-spring-cattr-example は CVS でのソース配布のみとなっています。 CVS へのアクセス方法は下記を参照してください。 http://wicket.sourceforge.net/cvs-usage.html
| プロジェクト名 | 説明 |
|---|---|
| wicket-spring | 基本モジュール |
| wicket-spring-annot | JDK5 アノテーションを使ったプロキシの生成のためのモジュール |
| wicket-spring-cattr | Jakarta commons attribute を使ったプロキシ生成のためのモジュール |
| wicket-spring-example | サンプル |
| wicket-spring-annot-example | |
| wicket-spring-cattr-example |
最新コメント