設定手順(Spring)
今回Springで使う設定項目は大きく分けて2か所です。
- データベースのトランザクション管理
- Struts 2のActionクラスとの紐付け
まずはトランザクション管理を設定しましょう。本サンプルではapplicationContext-transaction.xmlで設定しています。
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jee="http://www.springframework.org/schema/jee"
…(中略)…
>
<!-- トランザクション設定 -->
<!-- (A)トランザクション・マネージャ(JDBC) -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource"><ref bean="dataSource"/></property>
</bean>
<!-- (B)トランザクション定義(共通設定) -->
<bean id="txProxyTemplate" abstract="true"
class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<property name="transactionManager"><ref bean="transactionManager"/></property>
<property name="transactionAttributes">
<props>
<!-- (B')トランザクション監視を行うメソッド名とキャッチ例外ルール -->
<prop key="insert*,update*,delete*">
PROPAGATION_REQUIRED,
-java.lang.RuntimeException,
-java.lang.Error
</prop>
</props>
</property>
</bean>
<!-- (C)SpringからDAO生成する際の定義とアドバイザ差込定義 -->
<bean id="DAO" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="proxyInterfaces" value="seren.lumi2.dao.DAO" />
<property name="target" ref="DAOImpl" />
``</bean>
<!-- (D)Webコンテナからコネクションプールを取得 -->
<jee:jndi-lookup id="dataSource" jndi-name="java:comp/env/jdbc/localDB" />
<!-- (E)DAO定義 -->
<bean id="DAOImpl" class="seren.lumi2.dao.DAOImpl">
<property name="sqlMapClient" ref="sqlMapClient"/>
</bean>
<!-- (F)iBATIS設定層 -->
<bean id="sqlMapClient" class="org.springframework.orm.ibatis.SqlMapClientFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="configLocation" value="/WEB-INF/ibatis/sql-map-config.xml" />
</bean>
</beans>
やや複雑ですが順番に追って説明をしていきます。
(A)トランザクション管理をSpring管理で行う設定部分です。トランザクション管理を行う対象データソースの名前をdataSourceとします。
(B)トランザクション管理を行う際のSpringの設定です。(B')の部分で、トランザクション管理を行うメソッド名(*で省略も可能)を宣言し、例外検出時のトランザクション設定をします。先頭のPROPAGATION_REQUIREDはトランザクション取得定義(※1)であり、トランザクションを再利用し、もしない場合は新規で開始することを意味します。それ以降は、チェックする例外のクラスを並べます。+と-でコミット/ロールバックを設定します。通常、例外検出時はロールバックして欲しいので、-を設定しています。もし複数のSQLを用いてデータを更新し、例外の出たところまでをコミットしたいのであれば+で設定することになります。
(C)データベースとのアクセスを代替するクラス(DAO=DataAccessObject)を宣言します。DAOクラスのインターフェイスをproxyInterfacesの項で宣言し、そのインスタンスとなるオブジェクトをtargetで宣言します。これでDAOがSpring管理下におかれます。トランザクション管理機能との紐付けはこれ以降の設定で行います。
(D)Webコンテナからデータベースのコネクションプールを取得します。今回はWebコンテナでjndi名:jdbc/localDB(※2)で設定されていることを前提とします。
(E)DAOで扱うSQL定義を(F)で宣言するsqlMapClientで設定します。この(E)の設定は(C)で設定されたDAOImplであるため、Spring管理に入ります。
(F)Springが所持しているiBATISの管理クラスを利用します。この設定でデータソース(A)と設定ファイルの場所を記述します。
以上をまとめると、Webコンテナで設定されたJDBCのデータソース管理をSpring管理にし、(B')で設定されたメソッド名の先頭がinsert,update,deleteを実行した場合に、例外を検出するとロールバックします。
このように初期設定は大変ですが、一度設定しまえば余程のことがない限り微細な変更で済みます(このうち、自分の環境に応じて設定すべき設定すべき箇所は(C)~(E)の部分のみです)。
ではStruts 2のActionクラスをSpring管理下におく設定も書きましょう。
トランザクション取得定義にはいくつか存在し、Springはかなり特殊な設定も行えます。詳細はLinux+JavaによるWebアプリケーション構築メモ:Springのトランザクション管理機能を参照してください。今回のサンプルではごく単純かつ一般的に使われるトランザクション設定で行っています。
コンテナによってjndi名の指定方法が異なります。Tomcat5.5ではjava:comp/env/jdbc/localDBと宣言しないとなりません。JBoss4.xや5.xではjava:jdbc/localDBになります。
設定手順(Spring+Struts 2)
Spring設定ファイルで、Struts 2のActionクラスを設定します。ここで宣言することで、Spring管理にあるクラスを利用する場合に、Springに依存するコードは一切記述する必要がありません。
<!-- (A) SampleActionクラス -->
<bean id="sampleAction" parent="txProxyTemplate"
scope="request" class="seren.lumi2.action.SampleAction">
<!-- (B) Spring管理化にあるオブジェクトを取得 -->
<property name="DAO" ref="DAO" />
</bean>
(A)のbean要素で、Actionクラスの設定をします。それぞれの属性名については以下のとおりです。
| 名前 | 説明 |
| id | Actionクラスの設定名(任意かつ一意) |
| parent | 継承する設定内容。先ほど設定したトランザクション管理機能を利用するのでtxProxyTemplateを記述。 |
| scope | Actionクラスの寿命。requestで1リクエスト単位、sessionで1セッション単位で作成される。 |
| class | ActionクラスのFQDN名。 |
1つのActionクラスの設定はこれだけで済みます。もしDAOを使うActionが増えたとしても同じように増やしていけば良いだけなのでとても簡単にActionクラスを追加することができます。では今回使うごく簡単なサンプルを使って検索~新規登録~更新~削除を動きと設定内容を追ってみましょう。
