熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> Java編程 >> Java開源技術 >> 正文

Spring中的四種聲明式事務的配置

2013-11-23 20:28:01  來源: Java開源技術 

  Spring中的四種聲明式事務的配置Spring容器中有兩種思想很重要也就是我們常用的Ioc和Aop如果理解了這兩種思想對於我們學習設計模式和編程有很大的幫助美國四人幫(GOF)寫的設計模式中有很多都用到了Ioc的思想簡單的說就是依賴注入的思想常見的一種情況如果一個類中要復用另外一個類中的功能時我們可能會首先想到繼承如果你知道Ioc這種思想的話我想你不會用繼承你會馬上想到把要用到功能抽取出來在我們要用到的類中只需通過set方法簡單的注入就可以了其實這裡用到了對象的組合代替繼承這樣不僅避免了單一繼承還很好的實現了松耦合同時也遵循了面向對象的編程的設計原則多用組合少用繼承在這裡對於Ioc和Aop這兩種思想的好處我就不介紹了接下來我要說的是Spring中幾種常見的事務配置是Aop和Ioc的充分體現

  在說點題外話以前EJB在JEE中開發中可是大名鼎鼎的了就是因為EJB提供了很多服務而不需要我們去開發了其中用到最多的算是它提供的聲明式事務了在Spring沒有出現之前EJB在JEE開發中扮演著非常重要的角色同時也是很多項目失敗的罪魁禍首其中的原因就是因為它是重量級強侵入性收費的框架需要昂貴的服務器支持在加上它的測試更是讓人頭痛而Spring恰恰與它相反Spring是一個輕量級的非侵入性的開源框架它提供的聲明式事務的功能更是強大不需要容器的支持這一點吸引力很多人願意放棄EJB而使用Spring讓我們言歸正傳吧

  以下兩個bean的配置是下面要用到的

    <! 定義事務管理器(聲明式的事務) >
     <bean id=transactionManager
      class=orgspringframeworkormhibernateHibernateTransactionManager>
      <property name=sessionFactory>
       <ref local=sessionFactory />
      </property>
     </bean>
    <! *******業務邏輯層(是對各個DAO層的正面封裝)主要用到<<門面模式>>****** >
     <bean id=fundService
      class=comjackfundserviceserviceimplFundService>
      <property name=operdao>
       <ref bean=operatorDAO />
      </property>
      <property name=producedao>
       <ref bean=fundProduceDAO />
      </property>
      <property name=customerdao>
       <ref bean=customerDAO />
      </property>
      <property name=accountdao>
       <ref bean=accountDAO />
      </property>
      <property name=fundaccountdao>
       <ref bean=fundAccountDAO />
      </property>
      <property name=fundtransdao>
       <ref bean=fundTransDAO />
      </property>
     </bean>
    可能還有其他很多模塊<bean id=fundService/>可能只是其中的模塊

  第一種配置聲明式事務的方法如下也是我們最常用的方法了它適用於你的庫表比較少的情況下
    <bean id=fundServiceDAOProxy
      class=orgspringframeworktransactioninterceptorTransactionProxyFactoryBean>
      <! 配置事務管理器 >
      <property name=transactionManager>
       <ref bean=transactionManager />
      </property>
      <! 此屬性指定目標類本省是否是代理的對象如果目標類沒有實現任何類就設為true代表自己 >
      <property name=proxyTargetClass>
       <value>false</value>
      </property>
      <property name=proxyInterfaces>
       <value>comjackfundserviceIFundService</value>
      </property>
      <! 目標bean >
      <property name=target>
       <ref bean=fundService />
      </property>
      <! 配置事務屬性 >
      <property name=transactionAttributes>
       <props>
        <prop key=delete*>PROPAGATION_REQUIRED</prop>
        <prop key=add*>PROPAGATION_REQUIRED</prop>
        <prop key=update*>PROPAGATION_REQUIRED</prop>
        <prop key=save*>PROPAGATION_REQUIRED</prop>
        <prop   key=find*>PROPAGATION_REQUIREDreadOnly</prop>
       </props>
      </property>
     </bean>
     以下可能還有其他的xxxServiceDAOProxy大家可以看出針對每一個功能模塊配置一個業務代理服務如果模塊多大話就顯得代碼有點多了發現他們只是稍微一點不一樣這時我們就應該想到繼承的思想用第二種方法

第二種配置聲明式事務的方法如下這種情況適合相對比較多的模塊時使用
    <! 利用繼承的思想簡化配置要把abstract=true >
     <bean id=transactionBase
      class=orgspringframeworktransactioninterceptorTransactionProxyFactoryBean
      lazyinit=true abstract=true>
      <! 配置事務管理器 >
      <property name=transactionManager>
       <ref bean=transactionManager />
      </property>
      <! 配置事務屬性 >
      <property name=transactionAttributes>
       <props>
        <prop key=delete*>PROPAGATION_REQUIRED</prop>
        <prop key=add*>PROPAGATION_REQUIRED</prop>
        <prop key=update*>PROPAGATION_REQUIRED</prop>
        <prop key=save*>PROPAGATION_REQUIRED</prop>
        <prop key=find*>PROPAGATION_REQUIREDreadOnly</prop>
       </props>
      </property>
     </bean>
    而具體的模塊可以簡單的這樣配置只要指明它的parent(父類)就可以了父類一般把abstract=true因為在容器加載的時候不需要初始化等到用的時候再有它的子類調用的時候再去初始化
    <bean id=fundServiceDAOProxy parent=transactionBase >
      <property name=target>
      <ref bean=fundService />
      </property>
     </bean>
    這樣配置的話如果有多個像fundService這樣模塊時可以少些很多重復的代碼



第三種配置聲明式事務的方法如下主要利用BeanNameAutoProxyCreator自動創建事務代理
      <bean id=transactionInterceptor
      class=orgspringframeworktransactioninterceptorTransactionInterceptor>
      <property name=transactionManager>
       <ref bean=transactionManager />
      </property>
      <! 配置事務屬性 >
      <property name=transactionAttributes>
       <props>
        <prop key=delete*>PROPAGATION_REQUIRED</prop>
        <prop key=add*>PROPAGATION_REQUIRED</prop>
        <prop key=update*>PROPAGATION_REQUIRED</prop>
        <prop key=save*>PROPAGATION_REQUIRED</prop>
        <prop key=find*>PROPAGATION_REQUIREDreadOnly</prop>
       </props>
      </property>
     </bean>
     <bean
      class=orgspringframeworkaopframeworkautoproxyBeanNameAutoProxyCreator>
      <property name=beanNames>
       <list>
        <value>fundService</value>
       </list>
      </property>
      <property name=interceptorNames>
       <list>
        <value>transactionInterceptor</value>
       </list>
      </property>
     </bean>
    這種方法主要利用了攔截器的原理

    前三種方法一般都必需指定具體的模塊bean如果模塊過多話比如一個大型的網站一般有幾十個模塊我們就得考慮用第四種的配置方式了自動創建事務代理的方式了

  第四種配置聲明式事務的方法如下
    <bean id=transactionInterceptor
      class=orgspringframeworktransactioninterceptorTransactionInterceptor>
      <property name=transactionManager>
       <ref bean=transactionManager />
      </property>
    <! 自動代理 >
     <bean id=autoproxy
      class=orgspringframeworkaopframeworkautoproxyBeanNameAutoProxyCreator>
      <! 可以是Service或DAO層(最好是針對業務層*Service) >
      <property name=beanNames>
       <list>
        <value>*Service</value>
       </list>
      </property>
      <property name=interceptorNames>
       <list>
           <value>transactionInterceptor</value>
       </list>
      </property>
     </bean>
     自動代理還有一種用法就是結合正規表達式和advice使用
    <bean id=transactionInterceptor
      class=orgspringframeworktransactioninterceptorTransactionInterceptor>
      <property name=transactionManager>
       <ref bean=transactionManager />
      </property>
     <bean id=autoProxyCreator
      class=orgspringframeworkaopframeworkautoproxyDefaultAdvisorAutoProxyCreator />
    <bean id=regexpMethodPointcutAdvisor
      class=orgspringframeworkaopsupportRegexpMethodPointcutAdvisor>
      <property name=advice>
      <ref bean=transactionInterceptor />
      </property>
      <property name=pattern>
      <value>*</value>
      </property>
      </bean>
      這個方法可以針對具體的模塊進行攔截並進行事務處理在你的實際項目中你可以根據你的情況選用不同的方法


From:http://tw.wingwit.com/Article/program/Java/ky/201311/28539.html
  • 上一篇文章:

  • 下一篇文章:
  • 推薦文章
    Copyright © 2005-2013 電腦知識網 Computer Knowledge   All rights reserved.