すぐに始める Struts2 (Spring編)
前回の続き。
(Struts2単独のクイックスタートについては前回のエントリを参照のこと)
Struts2はSpringプラグインを使用することで Spring Framework 2.0と協調して動作できる。Springプラグインがクラスパスに追加されると、Struts2はアクションクラスのオブジェクトをインスタンス化するとき、そのファクトリとして Springの WebApplicationContextを使用するようになる。
これにより Struts2のアクションクラスは Springの管理下に置かれ、Springの作法で組み立てられたコンポーネントセットを利用できる。
spring.jar
cglib-nodep-2.1_3.jar
applicationContext.xmlの中で、アクションクラスを bean定義すれば良い。
前回の例で使ったアクションクラスを例に取ると下記のようになる。
(追記:アクションクラスの定義を applicationContext.xmlに書かなかった場合、依存性注入はプロパティ名とbean idの一致により自動的に行われるようだ)
アクションクラスへ注入して使う他のBeanに requestや sessionといった Web特有のスコープを適用したい場合、そのままscope属性をつけるだけでは実行時にスレッドが関連づけられていないといった趣旨のエラーが発生しまう。そのようなBeanに対しては <aop:scoped-proxy/> を埋め込んでやればAOPの力で問題が解決される。詳しくはScoped beans as dependenciesを参照のこと。
あと、アクションクラス内で xworkの Injectアノテーションを使って Spring管理下のBeanを注入できないかと思いやってみたのだが出来なかった。これが出来るといちいち applicationContext.xml内にアクションクラスをBean定義しなくても良いと思うのだが。
(Struts2単独のクイックスタートについては前回のエントリを参照のこと)
Struts2はSpringプラグインを使用することで Spring Framework 2.0と協調して動作できる。Springプラグインがクラスパスに追加されると、Struts2はアクションクラスのオブジェクトをインスタンス化するとき、そのファクトリとして Springの WebApplicationContextを使用するようになる。
これにより Struts2のアクションクラスは Springの管理下に置かれ、Springの作法で組み立てられたコンポーネントセットを利用できる。
/WEB-INF/libに入れるもの
struts2-spring-plugin-2.0.6.jarspring.jar
cglib-nodep-2.1_3.jar
/WEB-INF/web.xmlに書くこと
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
<listener>
<listener-class>
org.springframework.web.context.request.RequestContextListener
</listener-class>
</listener>
Spring用のBean定義ファイル
/WEB-INF/applicationContext.xmlとして作成する。アクションクラスを Springに登録
(追記:実はアクションクラスの定義は必ずしも applicationContext.xmlに書かなくても良いことが後に判明、ただし依存関係の構築をautowireに頼らず明示的に行いたければ書く必要がある)applicationContext.xmlの中で、アクションクラスを bean定義すれば良い。
前回の例で使ったアクションクラスを例に取ると下記のようになる。
<bean class="your.action.package.here.SimpleAction" scope="request">このように書けばアクションクラスと Beanはクラス名でマッチング(autowire)されるようだ。なおアクションクラスのスコープには request(Spring2.0から導入された新スコープ)を指定しておくこと。Springではscope指定を省略すると singletonになるため、忘れるとひどい問題を引き起こすだろう。
<!-- この中で好きにDependency Injectionを行う -->
</bean>
(追記:アクションクラスの定義を applicationContext.xmlに書かなかった場合、依存性注入はプロパティ名とbean idの一致により自動的に行われるようだ)
関係するBeanについての注意
(追記:アクションクラスの定義をapplicationContext.xmlに書かずに autowireに任せた場合は、自動的に不思議な力が働くようで、このことは気にしなくても良いようだ)アクションクラスへ注入して使う他のBeanに requestや sessionといった Web特有のスコープを適用したい場合、そのままscope属性をつけるだけでは実行時にスレッドが関連づけられていないといった趣旨のエラーが発生しまう。そのようなBeanに対しては <aop:scoped-proxy/> を埋め込んでやればAOPの力で問題が解決される。詳しくはScoped beans as dependenciesを参照のこと。

2 件のコメント:
あれー?
<constant name="struts.objectFactory" value="spring" />
これ書けばいいんじゃね?
struts.objectFactory = spring
でもいいけど。
すくなくともwebworkではobjectFactory=spring だけで、applicationContext.xmlにアクションの定義なんかしなくても動いたけどな。
今やってみたら、確かにアクションクラスの定義を書かなくてもBeanのIDでautowireされた。しかしこれ、名前の付け方に気をつけてないと、あらぬものがインジェクトされてしまう気が・・・。
どっちにしろstruts.objectFactoryは書かなくてもいいみたい。(classpathにspringプラグインがあるかどうかで勝手に動作を切り替えているようだ)
コメントを投稿
<< ホーム