《Spring in Action》筆記第三部分,涵蓋聲明式事務管理進階配置(自動代理、屬性來源、元數據)、Bean 繼承減少 XML 冗餘、Spring 與主流 Web 框架整合方式對比。
無需為每個 Service 手動配置 TransactionProxyFactoryBean,改用自動代理掃描所有 Advisor:
<bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"/>
<bean id="txAdvisor" class="org.springframework.transaction.interceptor.TransactionAttributeSourceAdvisor">
<property name="transactionInterceptor">
<bean class="org.springframework.transaction.interceptor.TransactionInterceptor">
<property name="transactionManager" ref="txManager"/>
<property name="transactionAttributeSource">
<bean class="org.springframework.transaction.interceptor.NameMatchTransactionAttributeSource">
<property name="properties">
<props>
<prop key="add*">PROPAGATION_REQUIRED</prop>
<prop key="update*">PROPAGATION_REQUIRED</prop>
<prop key="delete*">PROPAGATION_REQUIRED</prop>
<prop key="get*">PROPAGATION_SUPPORTS,readOnly</prop>
</props>
</property>
</bean>
</property>
</bean>
</property>
</bean>
所有 Bean 的方法名匹配模式者自動套用事務,新增 Service 無需修改 XML。
| 來源類別 | 特點 | 適用場景 |
|---|---|---|
| NameMatchTransactionAttributeSource | 方法名通配符匹配,配置簡單 | 命名規範專案,快速套用 |
| MethodMapTransactionAttributeSource | 精確指定 類.方法 → 屬性,支援通配符 | 需精細控制特定方法 |
| AttributesTransactionAttributeSource | JDK 1.5+ 註解 (@Transactional) / Commons Attributes | 現代專案首選,代碼即配置 |
<prop key="addUser">PROPAGATION_REQUIRED,-MyBusinessException,+RuntimeException</prop>
預設:RuntimeException 及 Error 回滾,checked exception 不回滾(符合 EJB 行為)。
TransactionProxyFactoryBean 重複屬性極多,抽取父 Bean:
<bean id="baseTxProxy" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"
abstract="true" lazy-init="true">
<property name="transactionManager" ref="txManager"/>
<property name="transactionAttributeSource" ref="txAttributeSource"/>
</bean>
<bean id="userService" parent="baseTxProxy">
<property name="target" ref="userServiceTarget"/>
</bean>
<bean id="orderService" parent="baseTxProxy">
<property name="target" ref="orderServiceTarget"/>
</bean>
abstract="true" + lazy-init="true" 避免父 Bean 被實例化,子 Bean 僅需指定 target。
| 框架 | 整合方式 | 核心類/配置 | 評價 |
|---|---|---|---|
| Struts 1.x | 1. Action 繼承 ActionSupport 2. DelegatingRequestProcessor | ContextLoaderPlugIn, DelegatingActionProxy | 方式 2 較解耦,但映射 path↔bean name 醜陋 |
| Tapestry | 自定義 Engine 注入 Spring Context | 繼承 BaseEngine,setupForRequest() 放入 Global | 需自行實作整合類,Spring 未內建 |
| JSF | 變數解析器委派 Spring | JSF-Spring 專案 (jsfspring.sourceforge.net) | 有獨立整合專案,較成熟 |
| WebWork 1.x | webwork.properties 設 ActionFactory | SpringActionFactory | 已停止維護 |
| WebWork 2.x / XWork | xwork.xml 設 externalReferenceResolver + Interceptor | SpringServletContextReferenceResolver, ExternalReferenceInterceptor | 較複雜,WebWork 2 併入 Struts 2 |
Spring 為各 ORM 提供統一 DaoSupport 基類:
HibernateDaoSupport // getSession(), closeSessionIfNecessary()
JdbcDaoSupport // getJdbcTemplate()
JdoDaoSupport
SqlMapClientDaoSupport // iBatis 2.x
SqlMapDaoSupport // iBatis 1.3
TopLinkDaoSupport
CciDaoSupport
繼承對應 DaoSupport 即可獲得模板/Session 便利方法,異常自動轉換為 DataAccessException 體系。
abstract="true" lazy-init="true"。DelegatingRequestProcessor,避免侵入 Action 代碼。@Transactional 註解 + <tx:annotation-driven/>,棄用 XML 事務配置。