naobe @ ウィキ

Spring

最終更新:

Bot(ページ名リンク)

- view
管理者のみ編集可
OpenSourceに戻る

Spring概要

  • DIxAOPコンテナ
  • DIを使い、疎な結合でクラスを注入する。DIを使っているため注入される上位層クラスのソースを修正しないで、下位層のクラスを取替え可能。よって下位層を改造しても上位層をテストする必要がない(変更に強い)。
  • Singletonを使わないで、単一インスタンスを提供する(デフォルト機能)。
  • 宣言的なトランザクション機能を持ち、AOPを使ってトランザクションをビジネスロジックと切り離して実装できる。
  • AOP(Aspect-Oriented Programming)。ソースを変更しないで、横断的(【例】あるパターンを持ったメソッド全て)に機能(ログ、トランザクション、例外処理、キャッシュなど)を追加する。

使用したバージョン

フレームワーク バージョン
spring 3.0.1
ibatis 2.3.4

Bean定義ファイル

Bean定義の大本となるファイル。services.xmlはクラスパス。後の2つのファイルは、このファイルのディレクトリからの相対パス。
 <beans>
   <import resource="services.xml"/>
   <import resource="resources/messageSource.xml"/>
   <import resource="/resources/themeSource.xml"/>
   <bean id="bean1" class="..."/>
   <bean id="bean2" class="..."/>
 </beans>

クラスパスを使う場合は、"classpath:/resources/themeSource.xml"と記述する。絶対パスを使う場合は、"file:C:/config/aaa.xml"と記述する。

Log4j

web.xmlに以下を追加。
<context-param>
	<param-name>log4jConfigLocation</param-name>
	<param-value>/WEB-INF/classes/resource/log4j.xml</param-value>
</context-param>
 <listener>
	<listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
</listener>

iBatis2.Xとの結合

ビーン定義ファイル

配置

WEB-INF/app-bean-context.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:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
   http://www.springframework.org/schema/context/spring-context-3.0.xsd
">
<!-- プレースホルダプロパティファイル設定 -->
<context:property-placeholder location="classpath:resource/ibatis/config.properties"/>	
<bean id="dataSource" class="org.apache.tomcat.dbcp.dbcp.BasicDataSource"
	destroy-method="close">
	<property name="driverClassName" value="${jdbc.driverClassName}" />
	<property name="url" value="${jdbc.url}" />
	<property name="username" value="${user}" />
	<property name="password" value="${passwd}" />
</bean>	
<bean id="sqlMapClient" class="org.springframework.orm.ibatis.SqlMapClientFactoryBean">
	<property name="configLocation" value="WEB-INF/classes/resource/ibatis/kakeiboMapConfig.xml" />
	<property name="dataSource" ref="dataSource" />
</bean>
<bean id="kakeiboDao" class="suna.screen.kakeibo.dao.KakeiboDaoImpl">
	<property name="sqlMapClient" ref="sqlMapClient"/>
</bean>
 </beans>

プロパティファイル

パス

WEB-INF/classes/resource/config.properties

記述

 user = user
 passwd = passwd
 jdbc.driverClassName = com.ibm.db2.jcc.DB2Driver
 jdbc.url = jdbc:db2://localhost:50000/suna

DAOクラス

 public class KakeiboDaoImpl extends SqlMapClientDaoSupport implements KakeiboDao {
  
   public List<Incident> selectIncident() {
     return getSqlMapClientTemplate().queryForList(SELECT_INCIDENT);
   }
 }

SQLマップ設定ファイル

パス

WEB-INF/classes/resource/ibatis/kakeiboMapConfig.xml ビーン定義ファイル参照

記述

 <?xml version="1.0" encoding="UTF-8" ?>
 <!DOCTYPE sqlMapConfig
 PUBLIC "-//ibatis.apache.org//DTD [[SQL]] Map Config 2.0//EN"
 "http://ibatis.apache.org/dtd/sql-map-config-2.dtd">
 <sqlMapConfig>
   <sqlMap resource="resource/ibatis/mapper/incidentMapper.xml" />
   <sqlMap resource="resource/ibatis/mapper/shusiNameMapper.xml" />
 </sqlMapConfig>

SQLマップファイル

パス

resource/ibatis/mapper/incidentMapper.xml クラスパス。

記述

 <?xml version="1.0" encoding="UTF-8" ?>
 <!DOCTYPE sqlMap
 PUBLIC "-//ibatis.apache.org//DTD SQL Map 2.0//EN"
 "http://ibatis.apache.org/dtd/sql-map-2.dtd">
 <sqlMap>
   <typeAlias alias="Incident" type="suna.screen.kakeibo.dao.Incident" />	
     <resultMap id="incidentResult" class="Incident">
       <result property="incid" column="incid" />
       <result property="incdate" column="incdate" />
       <result property="shusiname" column="shusiname" />
       <result property="nametype" column="nametype" />
       <result property="namedetail" column="namedetail" />
       <result property="price" column="price" />
     </resultMap>
     <select id="selectIncident" resultMap="incidentResult">
       select inc.INCID incid, inc.INCDATE incdate, name.NAME shusiname, name.NAMETYPE nametype, 
       detail.NAMEDETAIL namedetail, inc.PRICE price 
       from INOUTNAME name, INOUTDETAIL detail, INCIDENCE inc
       where inc.NAMEID = name.NAMEID AND inc.NAMEDETAILID = detail.NAMEDETAILID
     </select>
 </sqlMap>

SpringWEBアプリケーション適用



トランザクション

AOPを使ったトランザクション制御

設定ファイルを修正するだけで、トランザクションの追加が可能。設定したインタフェースの
特定のパターンのメソッド実行前後にトランザクションのビギン、コミットを実行するように設定する。

設定例は以下。interfaceのselectで始まるインタフェースを実行したときにread-onlyのトランザクションを
実行。select以外は、read-write。

AOP関係のjarがSpringにないため以下のサイトからaspectj-1.6.11.jarをダウンロード。
解凍してlibディレクトリ以下のjarファイルをインポート。
http://www.eclipse.org/aspectj/downloads.php

【インタフェース】
 package suna.screen.kakeibo.dao;
 
 public interface KakeiboDao {
 
 List<Incident> selectDayIncident(Calendar day, int type);
 
 List<Map<String, Object>> selectInout();
 
 List<Map<String, Object>> selectInout(int type);
 
 List<Map<String, Object>> selectDetail();
 
 void insertIncident(int year, int month, int day, String nameId, String detailId, int price);
 void deleteIncident(String[] incidentId);
 void insertInoutName(String name, String shusi);
 
          void insertInoutDetail(String detail);
 
          void deleteInoutName(String komoku);
 
          void deleteInoutDetail(String komoku);
 
          List<IncidentSummary> selectMonthSummary(int year, int month, int kubun);
 }
 
 
【ビーンコンテキスト設定ファイル】
 <?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:context="http://www.springframework.org/schema/context"
 xmlns:aop="http://www.springframework.org/schema/aop"
     xmlns:tx="http://www.springframework.org/schema/tx"
 xsi:schemaLocation="http://www.springframework.org/schema/beans
 http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
 http://www.springframework.org/schema/context
     http://www.springframework.org/schema/context/spring-context-3.0.xsd
     http://www.springframework.org/schema/tx
     http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
     http://www.springframework.org/schema/aop
     http://www.springframework.org/schema/aop/spring-aop-3.0.xsd"
 >
 
 <!-- プレースホルダプロパティファイル設定 -->
 <context:property-placeholder location="classpath:resource/ibatis/config.properties"/>
 
     <!-- トランザクションAOPアドバイス -->
 <tx:advice id="txAdvice" transaction-manager="txManager">
 <!-- the transactional semantics... -->
 <tx:attributes>
 <!-- selectで始まるメソッド -->
 <tx:method name="select*" read-only="true" propagation="REQUIRED"/>
 <!-- select以外デフォルト設定(read-only: false つまり、read-write) -->
 <tx:method name="*" propagation="REQUIRED"/>
 </tx:attributes>
 </tx:advice>
 
 <!-- AOPポイントカット -->
 <aop:config>
 <!-- KakeiboDaoインタフェースの全てのメソッドに対してtxAdviceを適用 -->
 <aop:pointcut id="kakeiboOperation"
 <!-- 
     expressionについては、http://www.eclipse.org/aspectj/doc/released/progguide/index.html参照  
 
     execution : call, within , withincode とも書ける。
                 callは、再起呼び出しでも呼ばれるが、executionはNG。他にも違いはあるが詳細は不明。
     第1引数:メソッドの戻り値
     第2引数:クラス.メソッド(引数)
 
     適用するメソッドをパターンで特定している。
 -->
 expression="execution(* suna.screen.kakeibo.dao.KakeiboDao.*(..))" />
 <aop:advisor advice-ref="txAdvice"
 pointcut-ref="kakeiboOperation" />
 </aop:config>
 
 <!-- [[Tomcat]]コネクションプール設定 -->
 <bean id="dataSource" class="org.apache.tomcat.dbcp.dbcp.BasicDataSource"
 destroy-method="close">
 <property name="driverClassName" value="${jdbc.driverClassName}" />
 <property name="url" value="${jdbc.url}" />
 <property name="username" value="${user}" />
 <property name="password" value="${passwd}" />
 </bean>
 <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
         <property name="dataSource" ref="dataSource"/>
     </bean>
 <bean id="sqlMapClient" class="org.springframework.orm.ibatis.SqlMapClientFactoryBean">
 <property name="configLocation" value="WEB-INF/classes/resource/ibatis/kakeiboMapConfig.xml" />
 <property name="dataSource" ref="dataSource" />
 </bean>
 
 <bean id="kakeiboDao" class="suna.screen.kakeibo.dao.KakeiboDaoImpl">
 <property name="sqlMapClient" ref="sqlMapClient"/>
 </bean>
 </beans>
 

【実行結果】
(1)select実行時
 2011.4.26 16:41:16.078 DEBUG DefaultListableBeanFactory[http-8080-1] - Returning cached instance of singleton bean 'ka  keiboDao'
 2011.4.26 16:41:16.125 DEBUG DataSourceTransactionManager[http-8080-1] - Creating new transaction with name [suna.scre  en.kakeibo.dao.KakeiboDao.selectDayIncident]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT,readOnly
 2011.4.26 16:41:22.906 DEBUG DataSourceTransactionManager[http-8080-1] - Acquired Connection [jdbc:db2://localhost:500  00/suna, UserName=suna, [[IBM]] [[DB2]] JDBC Universal Driver Architecture] for JDBC transaction
 2011.4.26 16:41:22.921 DEBUG DataSourceUtils[http-8080-1] - Setting JDBC Connection [jdbc:db2://localhost:50000/suna,   UserName=suna, IBM DB2 JDBC Universal Driver Architecture] read-only
 2011.4.26 16:41:23.093 DEBUG DataSourceTransactionManager[http-8080-1] - Switching JDBC Connection [jdbc:db2://localho  st:50000/suna, UserName=suna, IBM DB2 JDBC Universal Driver Architecture] to manual commit
 2011.4.26 16:41:23.093 DEBUG TransactionSynchronizationManager[http-8080-1] - Bound value [org.springframework.jdbc.da  tasource.ConnectionHolder@a166bd] for key [org.apache.tomcat.dbcp.dbcp.BasicDataSource@119db9e] to thread [http-8080-1  ]
 2011.4.26 16:41:23.093 DEBUG TransactionSynchronizationManager[http-8080-1] - Initializing transaction synchronization  
 2011.4.26 16:41:23.093 DEBUG TransactionInterceptor[http-8080-1] - Getting transaction for [suna.screen.kakeibo.dao.Ka  keiboDao.selectDayIncident]
 2011.4.26 16:41:23.093 DEBUG SqlMapClientTemplate[http-8080-1] - Opened SqlMapSession [com.ibatis.sqlmap.engine.impl.S  qlMapSessionImpl@ea443f] for [[iBATIS]] operation
 2011.4.26 16:41:23.109 DEBUG SqlMapClientTemplate[http-8080-1] - Obtained JDBC Connection [Transaction-aware proxy for   target Connection  from DataSource [org.apache.tomcat.dbcp.dbcp.BasicDataSource@119db9e]] for iBATIS operation
 2011.4.26 16:41:23.109 DEBUG TransactionSynchronizationManager[http-8080-1] - Retrieved value [org.springframework.jdb  c.datasource.ConnectionHolder@a166bd] for key [org.apache.tomcat.dbcp.dbcp.BasicDataSource@119db9e] bound to thread [h  ttp-8080-1]
 2011.4.26 16:41:23.156 DEBUG TransactionSynchronizationManager[http-8080-1] - Retrieved value [org.springframework.jdb  c.datasource.ConnectionHolder@a166bd] for key [org.apache.tomcat.dbcp.dbcp.BasicDataSource@119db9e] bound to thread [h  ttp-8080-1]
 2011.4.26 16:41:23.468 DEBUG TransactionSynchronizationManager[http-8080-1] - Retrieved value [org.springframework.jdb  c.datasource.ConnectionHolder@a166bd] for key [org.apache.tomcat.dbcp.dbcp.BasicDataSource@119db9e] bound to thread [h  ttp-8080-1]
 2011.4.26 16:41:23.468 DEBUG TransactionInterceptor[http-8080-1] - Completing transaction for [suna.screen.kakeibo.dao  .KakeiboDao.selectDayIncident]
 2011.4.26 16:41:23.468 DEBUG DataSourceTransactionManager[http-8080-1] - Triggering beforeCommit synchronization
 2011.4.26 16:41:23.468 DEBUG DataSourceTransactionManager[http-8080-1] - Triggering beforeCompletion synchronization
 2011.4.26 16:41:23.468 DEBUG DataSourceTransactionManager[http-8080-1] - Initiating transaction commit
 2011.4.26 16:41:23.468 DEBUG DataSourceTransactionManager[http-8080-1] - Committing JDBC transaction on Connection [jd  bc:db2://localhost:50000/suna, UserName=suna, IBM DB2 JDBC Universal Driver Architecture]
 2011.4.26 16:41:23.468 DEBUG DataSourceTransactionManager[http-8080-1] - Triggering afterCommit synchronization
 2011.4.26 16:41:23.468 DEBUG DataSourceTransactionManager[http-8080-1] - Triggering afterCompletion synchronization
 2011.4.26 16:41:23.468 DEBUG TransactionSynchronizationManager[http-8080-1] - Clearing transaction synchronization
 2011.4.26 16:41:23.468 DEBUG TransactionSynchronizationManager[http-8080-1] - Removed value [org.springframework.jdbc.  datasource.ConnectionHolder@a166bd] for key [org.apache.tomcat.dbcp.dbcp.BasicDataSource@119db9e] from thread [http-80  80-1]
 2011.4.26 16:41:23.468 DEBUG DataSourceUtils[http-8080-1] - Resetting read-only flag of JDBC Connection [jdbc:db2://lo  calhost:50000/suna, UserName=suna, IBM DB2 JDBC Universal Driver Architecture]
 2011.4.26 16:41:23.468 DEBUG DataSourceTransactionManager[http-8080-1] - Releasing JDBC Connection [jdbc:db2://localho  st:50000/suna, UserName=suna, IBM DB2 JDBC Universal Driver Architecture] after transaction
 2011.4.26 16:41:23.484 DEBUG DataSourceUtils[http-8080-1] - Returning JDBC Connection to DataSource
 
(1)insert実行時
 2011.4.26 16:46:51.875 DEBUG DataSourceTransactionManager[http-8080-1] - Creating new transaction with name [suna.scre  en.kakeibo.dao.KakeiboDao.insertIncident]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT
 2011.4.26 16:46:51.875 DEBUG DataSourceTransactionManager[http-8080-1] - Acquired Connection [jdbc:db2://localhost:500  00/suna, UserName=suna, IBM DB2 JDBC Universal Driver Architecture] for JDBC transaction
 2011.4.26 16:46:51.875 DEBUG DataSourceTransactionManager[http-8080-1] - Switching JDBC Connection [jdbc:db2://localho  st:50000/suna, UserName=suna, IBM DB2 JDBC Universal Driver Architecture] to manual commit
 2011.4.26 16:46:51.875 DEBUG TransactionSynchronizationManager[http-8080-1] - Bound value [org.springframework.jdbc.da  tasource.ConnectionHolder@a9a32c] for key [org.apache.tomcat.dbcp.dbcp.BasicDataSource@119db9e] to thread [http-8080-1  ]
 2011.4.26 16:46:51.875 DEBUG TransactionSynchronizationManager[http-8080-1] - Initializing transaction synchronization  
 2011.4.26 16:46:51.875 DEBUG TransactionInterceptor[http-8080-1] - Getting transaction for [suna.screen.kakeibo.dao.Ka  keiboDao.insertIncident]
 2011.4.26 16:46:51.890 DEBUG SqlMapClientTemplate[http-8080-1] - Opened SqlMapSession [com.ibatis.sqlmap.engine.impl.S  qlMapSessionImpl@114d18f] for iBATIS operation
 2011.4.26 16:46:51.890 DEBUG SqlMapClientTemplate[http-8080-1] - Obtained JDBC Connection [Transaction-aware proxy for   target Connection  from DataSource [org.apache.tomcat.dbcp.dbcp.BasicDataSource@119db9e]] for iBATIS operation
 2011.4.26 16:46:51.890 DEBUG TransactionSynchronizationManager[http-8080-1] - Retrieved value [org.springframework.jdb  c.datasource.ConnectionHolder@a9a32c] for key [org.apache.tomcat.dbcp.dbcp.BasicDataSource@119db9e] bound to thread [h  ttp-8080-1]
 2011.4.26 16:46:51.890 DEBUG TransactionSynchronizationManager[http-8080-1] - Retrieved value [org.springframework.jdb  c.datasource.ConnectionHolder@a9a32c] for key [org.apache.tomcat.dbcp.dbcp.BasicDataSource@119db9e] bound to thread [h  ttp-8080-1]
 2011.4.26 16:46:52.015 DEBUG TransactionSynchronizationManager[http-8080-1] - Retrieved value [org.springframework.jdb  c.datasource.ConnectionHolder@a9a32c] for key [org.apache.tomcat.dbcp.dbcp.BasicDataSource@119db9e] bound to thread [h  ttp-8080-1]
 2011.4.26 16:46:52.015 DEBUG TransactionInterceptor[http-8080-1] - Completing transaction for [suna.screen.kakeibo.dao  .KakeiboDao.insertIncident]
 2011.4.26 16:46:52.015 DEBUG DataSourceTransactionManager[http-8080-1] - Triggering beforeCommit synchronization
 2011.4.26 16:46:52.015 DEBUG DataSourceTransactionManager[http-8080-1] - Triggering beforeCompletion synchronization
 2011.4.26 16:46:52.015 DEBUG DataSourceTransactionManager[http-8080-1] - Initiating transaction commit
 2011.4.26 16:46:52.015 DEBUG DataSourceTransactionManager[http-8080-1] - Committing JDBC transaction on Connection [jd  bc:db2://localhost:50000/suna, UserName=suna, IBM DB2 JDBC Universal Driver Architecture]
 2011.4.26 16:46:52.015 DEBUG DataSourceTransactionManager[http-8080-1] - Triggering afterCommit synchronization
 2011.4.26 16:46:52.031 DEBUG DataSourceTransactionManager[http-8080-1] - Triggering afterCompletion synchronization
 2011.4.26 16:46:52.031 DEBUG TransactionSynchronizationManager[http-8080-1] - Clearing transaction synchronization
 2011.4.26 16:46:52.031 DEBUG TransactionSynchronizationManager[http-8080-1] - Removed value [org.springframework.jdbc.  datasource.ConnectionHolder@a9a32c] for key [org.apache.tomcat.dbcp.dbcp.BasicDataSource@119db9e] from thread [http-80  80-1]
 2011.4.26 16:46:52.031 DEBUG DataSourceTransactionManager[http-8080-1] - Releasing JDBC Connection [jdbc:db2://localho  st:50000/suna, UserName=suna, IBM DB2 JDBC Universal Driver Architecture] after transaction
 2011.4.26 16:46:52.031 DEBUG DataSourceUtils[http-8080-1] - Returning JDBC Connection to DataSource

WebSphereUowTransactionManager

内部で、UOWManagerをJNDIルックアップして使用している。たぶんWebSphereが動いていないと利用できない。
添付ファイル
人気記事ランキング
ウィキ募集バナー