本文主要探討如何利用SPRing來裝配組件,包括其事務上下文。從J2EE應用程序內部連接到單個的數據庫并不是什么難事。但是,假如要裝配或者集成企業級的組件,情況就復雜了。一個組件可以有一個或多個支持它的數據庫,因此,當裝配兩個或更多的組件時,我們希望能夠保持在跨組件的多個數據庫中進行的操作的原子性。J2EE服務器為這些組件提供了一個容器來保證事務原子性和跨組件獨立性。假如使用的不是J2EE服務器,則可以利用Spring來幫助我們。Spring基于Inversion of Control(控制反轉)模式(也稱為依靠注入),它不僅可以連接組件服務,還可以連接關聯的事務上下文。在本文中,我們將Hibernate用作對象/關系持久性存儲和查詢服務?! ?/P>
裝配組件事務
假設在企業組件庫里,我們已經有一個審計組件,里面有可以被客戶端調用的服務方法。然后,當我們想要構建一個訂單處理系統時,我們發現存在這樣的設計要求:OrderListManager組件服務同樣需要審計組件服務。OrderListManager創建和治理訂單,因此所有的OrderListManager服務都有自己的事務屬性。當我們從OrderListManager服務內調用審計組件時,我們實際上是在把OrderListManager服務的事務上下文傳播給審計服務。也許將來新的業務服務組件同樣需要審計組件,但那時將在一個不同的事務上下文中調用它。實際結果就是,即使審計組件的功能保持不變,它也可能是由別的業務服務功能組成,包含了混搭的(mix-and-match)事務屬性來提供不同的運行時事務性行為。
在圖1中有兩個獨立的調用上下文流程。在流程1里,假如客戶端有TX上下文,那么OrderListManager既可以參與其中,也可以啟動一個新的TX,這取決于客戶端是否在TX中,以及為OrderListManager方法指定了什么樣的TX屬性。這同樣適用于OrderListManager服務依次調用AuditManager方法的情況。
圖1 裝配組件事務
EJB架構答應組件裝配者聲明式地給出正確的事務屬性,從而為他們提供這種靈活性。我們不探討聲明式事務治理的替代方案(即所謂的編程式事務控制),因為這會牽涉到代碼更改,從而產生不同的運行時事務行為。幾乎所有的J2EE應用服務器都按照X/Open XA規范提供了服從兩階段提交協議的分布式事務治理器?,F在的問題是,我們能不能利用EJB服務器來實現相同的功能?Spring就是其中的一種解決方案。讓我們來看一下Spring如何幫助我們解決事務組裝的問題:
使用Spring進行事務治理
我們將看到一個輕量級的事務基礎架構,它實際上可以治理組件級的事務裝配。Spring是其中的一個解決方案。它的優點在于,我們不會被捆綁到J2EE容器服務(如JNDI DataSource)上。最棒的一點是,假如我們想把這個輕量級事務基礎架構關聯到一個已可用的J2EE容器基礎架構,將不會有任何問題??雌饋砦覀兛梢岳脙烧叩膬烖c。
另一方面,Spring這個輕量級事務基礎架構使用了一個面向方面編程(aspect-Oriented Programming,AOP)框架。Spring AOP框架使用了一個支持AOP的Spring bean工廠。在特定于Spring的配置文件applicationContext.xml中,通過在組件服務級指定事務特性來劃分事務。
<beans>
<!-- other code goes here... -->
<bean id="orderListManager"
class="org.springframework.transaction
.interceptor.TransactionProxyFactoryBean">
<property name="transactionManager">
<ref local="transactionManager1"/>
</property>
<property name="target">
<ref local="orderListManagerTarget"/>
</property>
<property name="transactionAttributes">
<props>
<prop key="getAllOrderList">
PROPAGATION_REQUIRED
</prop>
<prop key="getOrderList">
PROPAGATION_REQUIRED
</prop>
<prop key="createOrderList">
PROPAGATION_REQUIRED
</prop>
<prop key="addLineItem">
PROPAGATION_REQUIRED,
-com.example.exception.FacadeException
</prop>
<prop key="getAllLineItems">
PROPAGATION_REQUIRED,readOnly
</prop>
<prop key="queryNumberOfLineItems">
PROPAGATION_REQUIRED,readOnly
</prop>
</props>
</property>
</bean>
新聞熱點
疑難解答