Spring中的四種聲明式事務(wù)的配置
如果理解了這兩種思想,對(duì)于我們學(xué)習(xí)設(shè)計(jì)模式和編程有很大的幫助,美國(guó)四人幫(GOF)寫(xiě)的設(shè)計(jì)模式中,有很多都用到了Ioc的思想。簡(jiǎn)單的說(shuō)就是依賴注入的思想。常見(jiàn)的一種情況:如果一個(gè)類中要復(fù)用另外一個(gè)類中的功能時(shí),我們可能會(huì)首先想到繼承,如果你知道Ioc這種思想的話,我想你不會(huì)用繼承,你會(huì)馬上想到把要用到功能抽取出來(lái),在我們要用到的類中只需通過(guò)set方法簡(jiǎn)單的注入就可以了,其實(shí)這里用到了對(duì)象的組合代替繼承,這樣不僅避免了單一繼承,還很好的實(shí)現(xiàn)了松耦合。同時(shí)也遵循了面向?qū)ο蟮木幊痰脑O(shè)計(jì)原則:多用組合,少用繼承。在這里對(duì)于Ioc和Aop這兩種思想的好處。我就不介紹了。接下來(lái)我要說(shuō)的是Spring中幾種常見(jiàn)的事務(wù)配置,是Aop和Ioc的充分體現(xiàn)。
在說(shuō)點(diǎn)題外話,以前EJB在J2EE中開(kāi)發(fā)中可是大名鼎鼎的了。就是因?yàn)镋JB提供了很多服務(wù),而不需要我們?nèi)ラ_(kāi)發(fā)了,其中用到最多的算是它提供的聲明式事務(wù)了。在Spring沒(méi)有出現(xiàn)之前,EJB在J2EE開(kāi)發(fā)中扮演著非常重要的角色。同時(shí)也是很多項(xiàng)目失敗的罪魁禍?zhǔn)?。其中的原因就是因?yàn)樗侵亓考?jí),強(qiáng)侵入性收費(fèi)的框架。需要昂貴的服務(wù)器支持,在加上它的測(cè)試更是讓人頭痛。而Spring恰恰與它相反。Spring是一個(gè)輕量級(jí)的,非侵入性的開(kāi)源框架。它提供的聲明式事務(wù)的功能更是強(qiáng)大,不需要容器的支持。這一點(diǎn)吸引力很多人愿意放棄EJB而使用Spring.讓我們言歸正傳吧。
以下兩個(gè)bean的配置是下面要用到的。
- <bean id="transactionManager"
- class="org.springframework.orm.hibernate3.HibernateTransactionManager">
- <property name="sessionFactory">
- <ref local="sessionFactory" />
- < SPAN>property>
- < SPAN>bean>
- <bean id="fundService"
- class="com.jack.fund.service.serviceimpl.FundService">
- <property name="operdao">
- <ref bean="operatorDAO" />
- < SPAN>property>
- <property name="producedao">
- <ref bean="fundProduceDAO" />
- < SPAN>property>
- <property name="customerdao">
- <ref bean="customerDAO" />
- < SPAN>property>
- <property name="accountdao">
- <ref bean="accountDAO" />
- < SPAN>property>
- <property name="fundaccountdao">
- <ref bean="fundAccountDAO" />
- < SPAN>property>
- <property name="fundtransdao">
- <ref bean="fundTransDAO" />
- < SPAN>property>
- < SPAN>bean>
可能還有其他很多模塊。
***種:配置聲明式事務(wù)的方法如下。也是我們最常用的方法了,它適用于你的庫(kù)表比較少的情況下。
- <bean id="fundServiceDAOProxy"
- class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
- <property name="transactionManager">
- <ref bean="transactionManager" />
- < SPAN>property>
- <property name="proxyTargetClass">
- <value>false< SPAN>value>
- < SPAN>property>
- <property name="proxyInterfaces">
- <value>com.jack.fund.service.IFundService< SPAN>value>
- < SPAN>property>
- <property name="target">
- <ref bean="fundService" />
- < SPAN>property>
- <property name="transactionAttributes">
- <props>
- <prop key="delete*">PROPAGATION_REQUIRED< SPAN>prop>
- <prop key="add*">PROPAGATION_REQUIRED< SPAN>prop>
- <prop key="update*">PROPAGATION_REQUIRED< SPAN>prop>
- <prop key="save*">PROPAGATION_REQUIRED< SPAN>prop>
- <prop key="find*">PROPAGATION_REQUIRED,readOnly< SPAN>prop>
- < SPAN>props>
- < SPAN>property>
- < SPAN>bean>
以下可能還有其他的xxxServiceDAOProxy.大家可以看出針對(duì)每一個(gè)功能模塊配置一個(gè)業(yè)務(wù)代理服務(wù)。如果模塊多大話,就顯得代碼有點(diǎn)多了,發(fā)現(xiàn)他們只是稍微一點(diǎn)不一樣。這時(shí)我們就應(yīng)該想到繼承的思想。用第二種方法。
第二種:配置聲明式事務(wù)的方法如下。這種情況適合相對(duì)比較多的模塊時(shí)使用。
- <bean id="transactionBase"
- class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"
- lazy-init="true" abstract="true">
- <property name="transactionManager">
- <ref bean="transactionManager" />
- < SPAN>property>
- <property name="transactionAttributes">
- <props>
- <prop key="delete*">PROPAGATION_REQUIRED< SPAN>prop>
- <prop key="add*">PROPAGATION_REQUIRED< SPAN>prop>
- <prop key="update*">PROPAGATION_REQUIRED< SPAN>prop>
- <prop key="save*">PROPAGATION_REQUIRED< SPAN>prop>
- <prop key="find*">PROPAGATION_REQUIRED,readOnly< SPAN>prop>
- < SPAN>props>
- < SPAN>property>
- < SPAN>bean>
- 而具體的模塊可以簡(jiǎn)單的這樣配置。只要指明它的parent(父類)就可以了。父類一般把abstract="true",因?yàn)樵谌萜骷虞d的時(shí)候不需要初始化,等到用的時(shí)候再有它的子類調(diào)用的時(shí)候,再去初始化。
- <bean id="fundServiceDAOProxy" parent="transactionBase" >
- <property name="target">
- <ref bean="fundService" />
- < SPAN>property>
- < SPAN>bean>
這樣配置的話,如果有多個(gè)像fundService這樣模塊時(shí),可以少些很多重復(fù)的代碼。
第三種:配置聲明式事務(wù)的方法如下。主要利用BeanNameAutoProxyCreator自動(dòng)創(chuàng)建事務(wù)代理
- <bean id="transactionInterceptor"
- class="org.springframework.transaction.interceptor.TransactionInterceptor">
- <property name="transactionManager">
- <ref bean="transactionManager" />
- < SPAN>property>
- <property name="transactionAttributes">
- <props>
- <prop key="delete*">PROPAGATION_REQUIRED< SPAN>prop>
- <prop key="add*">PROPAGATION_REQUIRED< SPAN>prop>
- <prop key="update*">PROPAGATION_REQUIRED< SPAN>prop>
- <prop key="save*">PROPAGATION_REQUIRED< SPAN>prop>
- <prop key="find*">PROPAGATION_REQUIRED,readOnly< SPAN>prop>
- < SPAN>props>
- < SPAN>property>
- < SPAN>bean>
- <bean
- class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
- <property name="beanNames">
- <list>
- <value>fundService< SPAN>value>
- < SPAN>list>
- < SPAN>property>
- <property name="interceptorNames">
- <list>
- <value>transactionInterceptor< SPAN>value>
- < SPAN>list>
- < SPAN>property>
- < SPAN>bean>
這種方法主要利用了攔截器的原理。
前三種方法一般都必需指定具體的模塊bean.如果模塊過(guò)多話,比如一個(gè)大型的網(wǎng)站一般有幾十個(gè)模塊。我們就得考慮用第四種的配置方式了。自動(dòng)創(chuàng)建事務(wù)代理的方式了。
第四種:配置聲明式事務(wù)的方法如下。
- <bean id="transactionInterceptor"
- class="org.springframework.transaction.interceptor.TransactionInterceptor">
- <property name="transactionManager">
- <ref bean="transactionManager" />
- < SPAN>property>
- <bean id="autoproxy"
- class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
- <property name="beanNames">
- <list>
- <value>*Service< SPAN>value>
- < SPAN>list>
- < SPAN>property>
- <property name="interceptorNames">
- <list>
- <value>transactionInterceptor< SPAN>value>
- < SPAN>list>
- < SPAN>property>
- < SPAN>bean>
自動(dòng)代理還有一種用法就是結(jié)合正規(guī)表達(dá)式和advice使用。
- <bean id="transactionInterceptor"
- class="org.springframework.transaction.interceptor.TransactionInterceptor">
- <property name="transactionManager">
- <ref bean="transactionManager" />
- < SPAN>property>
- <bean id="autoProxyCreator"
- class="org.springframework.aop.framework.autoproxy.DefaultAdvisor AutoProxyCreator" />
- <bean id="regexpMethodPointcutAdvisor"
- class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
- <property name="advice">
- <ref bean="transactionInterceptor" />
- < SPAN>property>
- <property name="pattern">
- <value>.*< SPAN>value>
- < SPAN>property>
- < SPAN>bean>
【編輯推薦】