連携方法を拡張して、より自由度が高い連携をするには? | Java Springの逆引きメモ

Java Springの逆引きメモ

JavaのSpring frameworkのメモを書いていきます!
初心者の勉強ノートなので間違いがあるかもしれませんが、何かヒントになることがあれば幸いです。

前の記事にて、4つの連携方法をみました。

その中では、DelegatingActionProxyを使用する方法が良さそうという結論を出しました。


それでも、以下の弱点があることも書きました。


 1.Strutsのactionに設定するpathと同じidでSpring設定ファイルにActionクラスを設定しないといけません。

  ですので、1つパスが増えると2つのファイルに記述をしないといけないという問題があります。

 2.Springであれば、beanの使い回しができるのが当たり前ですが、beanのidをパス名と合わせない

  といけないです。ですので、同じActionクラスでも、path名が違えば、違うbeanとして設定しないといけません。 

 3.もうひとつ、beanのid名を自由に選べないという弱点もあります。



1を解決することはできませんが、2と3は解決できます。

その方法を見てみましょう。


一つ断っておくと、これは自分独自のやり方です。

Springなどでスタンダードなやり方は前の記事の4つのうちのどれかです。


でも、たぶん問題ないかとは思いますが、参考にするのは自己責任でラブラブお願いします。




【新たなProxyの作成】

以下のクラスを作ります。

StrutsのコンフィグファイルからBean名を取得するように変更しています。

import org.apache.commons.validator.GenericValidator;
import org.apache.struts.action.ActionMapping;
import org.springframework.beans.FatalBeanException;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.struts.DelegatingActionProxy;
public class MyProxy extends DelegatingActionProxy { /** * actionタグのproertyタグ、parameter属性の値を順番に取得し、nullでない方をbean名として返す。 */ protected String determineActionBeanName(ActionMapping mapping) { //bean名の取得(propertyから) String beanName = mapping.getProperty("spring-bean"); if(!GenericValidator.isBlankOrNull(beanName)){ return beanName; } //propertyで見つからないとき、パラメターからbean名を取得 beanName = mapping.getParameter(); if(!GenericValidator.isBlankOrNull(beanName)){ return beanName; } //どちらからも見つからない場合 throw new FatalBeanException("struts-config error, " + "should set 'spring-bean' property or 'parameter' attibute."); } }




【Strutsファイルの設定】

Strutsのファイルには以下のようにset-propertyでSpringのbeanのidを設定する。

ここではtestActionというbeanを設定しています。


<action path="/test" type="MyProxy" scope="request" >
<set-property key="spring-bean" value="testAction"/>

</action>


【Springファイルの設定】

Springのファイルには以下のように、普通にbeanの設定をします。


<bean id="testAction" class="presentation.action.TestAction" />



もしくは、以下のようにスキャンを使って指定のパッケージ配下のクラスを自動でDIします。

この場合、bean名はクラス名の先頭を小文字にしたものになります。

これなら楽ですねにひひ


<context:component-scan base-package="presentation.action" annotation-config="false">
  <context:include-filter type="regex" expression=".*Action"/>
</context:component-scan>

  ※もちろんAction内のプロパティのDIは、@AutoWiredか@Resourceを使用します


【説明】

Strutsのactionタグのパス名とSpringのbean名が違うことが分かるでしょうか?

変わりに、actionのtype属性には先ほど作成したMyProxyを設定しています。


Springが提供するDelegatingActionProxy クラスは、機能拡張しやすいように機能をこまめにメソッドにしています。

determineActionBeanNameメソッドは、こまめに変更できるようにしたメソッドの一つで、Strutsに設定したパス名をmappingから取得し返却する役割を持っています。

このメソッドの呼び出し元では、返却されたパス名と同名のbeanをSpringのApplicationContextから取得する処理を行っています。

ですので、このメソッドを変更するだけで目的を達成できます!

これだけです。

でも、これにより、さまざまなことができます。

それは応用例で!


他にも機能を変更したい場合、DelegatingActionProxy クラスのソースを見てみましょう。

たいていの場合、やりたいことをオーバーライドするだけでできると思います。



【応用例】

例えば、MyProxyをさらに拡張してAという機能をつけたとしましょう。


そして、Strutsの設定ファイルに以下のように記述します

<action path="/extest" type="MyProxyA" scope="request" >
<set-property key="spring-bean" value="testAction"/>

</action>


すると、Springのbeanの設定の変更無くパスを追加できて、

しかもAという機能が付いた画面を提供できます。


再利用性が高まったでしょ?



参考:

Strutsと連携するには?(理論編)

Strutsと連携するには?(実践編)