Spring+hibernate實(shí)戰(zhàn)(二)

          項(xiàng)目很小,主體部分也完成的差不多了,但麻雀雖小,五臟具全,我在其中用到了springIoCtransaction管理,也用到了簡(jiǎn)單的AOP功能,同時(shí)使用了spring mvc,下面我對(duì)它們做一些總結(jié),也跟和我一樣剛剛踏入spring大門的兄弟們探討探討:

          (一)spring IoC探討

          先還是談?wù)?/SPAN>spring IoC的使用。IoC也就是控制反轉(zhuǎn),即由容器來調(diào)用你的代碼,而你不用去使用容器的接口,一般都用好萊塢原則來進(jìn)行形象的比喻。最近在看那本without EJB才知道其實(shí)DI(依賴注入)其實(shí)只是IoC的一種實(shí)現(xiàn),而DI又分為set注入和constructor注入。更輕量級(jí)的IoC容器PicoContainer就是采用constructor注入,spring兩種都支持,但Rod Johnson經(jīng)過詳細(xì)的比較,建議還是一般采用set注入方式。理解set注入,對(duì)使用和深入了解spring框架非常重要。

          為了做到面向接口編程,我們總是盡量使用接口聲明,但接口是不能new的,如果不使用IoC容器,終歸需要個(gè)地方new它的實(shí)現(xiàn)類。如Interface a=new InterfaceImpl(),這樣還是在代碼中形成了對(duì)實(shí)現(xiàn)類的依賴。當(dāng)然我們可以使用factory模式來將聲明提取到工廠類中,但這樣又形成了對(duì)工廠的依賴,而且工廠也會(huì)越來越多,不便于管理。于是我們通過配置如

           

          <bean id="emailAdvisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">

          這樣在配置文件中聲明其實(shí)現(xiàn)類,就消除了對(duì)具體實(shí)現(xiàn)類的耦合。而一個(gè)類通常需要放置其它類的引用,或者使用從其它配置文件讀出的值,這個(gè)時(shí)候就是set注入顯示威力的時(shí)候了。

          <bean id="msg" class="org.springframework.mail.SimpleMailMessage">

                 
          <property name="from" value="${mail.from}" />

              bean>這是聲明一個(gè)Message對(duì)象實(shí)例的配置文件,${mail.from}表明是在*.properties文件配置的值,看到這個(gè)我們就知道SimpleMailMessage是一個(gè)具體類,有一個(gè)from的屬性,同時(shí)有一個(gè)setFrom的公共方法。SpringContextLoader在啟動(dòng)時(shí)就會(huì)自動(dòng)創(chuàng)建一個(gè)SimpleMailMessage對(duì)象的實(shí)例,并將mail.from對(duì)應(yīng)的值用set方法注入進(jìn)去,spring默認(rèn)會(huì)創(chuàng)建Singleton對(duì)象。以后碰到需要配置的什么參數(shù),就可以采用這種方式注入,注意.properties文件還是分個(gè)類較好,如jdbc.properties配置數(shù)據(jù)庫(kù)訪問參數(shù),mail.properties配置郵件參數(shù)(我這也是學(xué)的jpetstore的)。

          以下配置就是將一個(gè)mailSender和一個(gè)msg引用注入到一個(gè)emailAdvice中去。emailAdvice使用的是他們的接口聲明,然后加上set方法,而不關(guān)心它們是用什么實(shí)現(xiàn)類。

          <bean id="emailAdvice" class="com.bankcomm.vpn.service.SendMailAdvice">

                 
          <property name="mailSender" ref="mailSender" />

                 
          <property name="msg" ref="msg" />

          </bean
          >

          講一個(gè)巧妙使用spring set注入解決實(shí)際問題的例子。系統(tǒng)要求某些用戶有審批的權(quán)限,通常我們使用數(shù)據(jù)庫(kù),但由于是小項(xiàng)目,能審批的用戶也不多,我又不想寫什么Dao,于是希望能在配置文件中直接定義。如果不使用spring,在以往項(xiàng)目中的做法就是定義一個(gè)xml文件,然后寫方法去解析文件,把配置的用戶讀取到一個(gè)config類中,這個(gè)過程又必須在系統(tǒng)啟動(dòng)時(shí)進(jìn)行,所以有個(gè)StarterServlet,在啟動(dòng)后調(diào)用這個(gè)方法,StarterServlet又需要定義在web.xml中。是不是很復(fù)雜?

          有了spring,我們就有了新的選擇。先看下面的配置文件:

                

          <bean id="auditer" class="com.bankcomm.vpn.service.Auditer">

                     
          <property name="auditers">

                        
          <list>

                            
          <value>info1value>

                          
          <value>info2value>

                           

                        
          </list>

                     
          </property>

                 
          </bean>

          為簡(jiǎn)單起見,我沒有使用接口,直接定義了一個(gè)Auditer類,它有一個(gè)List類型的auditers屬性,然后加個(gè)set方法。對(duì)auditers里面的值,就使用spring支持的list配置方式進(jìn)行注入。你可以配多個(gè)valuecontextLoader啟動(dòng)時(shí)就會(huì)自動(dòng)把這些value填入一個(gè)ArrayList實(shí)現(xiàn),然后setauditer類中,你就可以直接使用這個(gè)類了。你看,是不是很方便就實(shí)現(xiàn)了這個(gè)功能,這也從一個(gè)方面體現(xiàn)了spring的強(qiáng)大之處。

          (二)spring transaction管理探討

          說到transaction管理,其實(shí)我也沒有太多經(jīng)驗(yàn)(項(xiàng)目經(jīng)驗(yàn)太少!),以前寫jdbc代碼,就是使用setAutoCommit(false)來實(shí)現(xiàn),要用到JTA來實(shí)現(xiàn)跨數(shù)據(jù)庫(kù)的情況還沒碰到過。所以這里就簡(jiǎn)單講講如何寫spring配置文件來支持transaction的聲明式配置。

          <bean id="baseTransactionProxy" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"

                   
          abstract="true">

                 
          <property name="transactionManager" ref="transactionManager"/>

                 
          <property name="transactionAttributes">

                     
          <props>

                        
          <prop key="insert*">PROPAGATION_REQUIRED</prop>

                        
          <prop key="update*">PROPAGATION_REQUIRED</prop>

                        
          <prop key="*">PROPAGATION_REQUIRED,readOnlyprop>

                     
          </props>

                 
          </property>

              
          </bean>

          以上配置文件就是定義了一個(gè)baseTransactionProxy 對(duì)象,它注入一個(gè)transactionManager對(duì)象,并注入一個(gè)transactionAttributesProperties對(duì)象,這個(gè)Properties對(duì)象的配置就是內(nèi)配置的內(nèi)容。transactionManager可以根據(jù)你的需要來進(jìn)行配置,如使用hibernate,可以用

          <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager"><property name="sessionFactory" ref="sessionFactory"/></bean>

          來配置。如果使用JTA就使用

          <bean id="transactionManager" class="org.springframework.transaction.jta.JtaTransactionManager"/>

          這里很方便就能切換到另一種transactionManager的實(shí)現(xiàn)上去。PROPAGATION_REQUIRED表明會(huì)放入當(dāng)前的事務(wù)中,如果沒有就創(chuàng)建一個(gè)。Readonly表明此方法只讀,能提高速度,spring還支持隔離級(jí)別的配置,具體配置說明,可以看springapi文檔http://www.springframework.org/docs/api/org/springframework/transaction/TransactionDefinition.html

          有了這個(gè)baseTransactionProxy,我們就可以用下面的配置使service層的Fa?ade對(duì)象具備事務(wù)管理功能了。這里VpnImpl 為一個(gè)Fa?ade接口的實(shí)現(xiàn)類,它實(shí)現(xiàn)對(duì)Dao層的代理然后,提供對(duì)外的統(tǒng)一接口。好處就是只有一個(gè)接口類,對(duì)transaction的配置和其它AOP配置都可以針對(duì)這個(gè)Fa?ade進(jìn)行,希望詳細(xì)了解Fa?ade模式可以參看模式相關(guān)書籍。

          <bean id="vpn" parent="baseTransactionProxy">

                 
          <property name="target">

                     
          <bean class="com.bankcomm.vpn.service.VpnImpl">

                        
          <property name="userDao" ref="userDao" />

                        
          <property name="submitVpnRequest" ref="submitVpnRequest" />

                     
          </bean>

                 
          </property>

                 
          <property name="postInterceptors">

                     
          <list>

                        
          <ref bean="emailAdvisor" />

                     
          </list>

                 
          </property>

              
          </bean>

          有了springtransaction管理,聲明式事務(wù)就不再是EJB所獨(dú)有了,我們可以使用spring的事務(wù),而避免僅僅因?yàn)橐暶魇绞聞?wù)而使用EJB這樣重量級(jí)的東西了。

                 先寫到這里吧,下篇我再繼續(xù)AOPspring mvc的討論。

          posted on 2005-11-07 16:02 pesome 閱讀(2559) 評(píng)論(0)  編輯  收藏 所屬分類: Spring+Struts+Hibernate

          <2005年11月>
          303112345
          6789101112
          13141516171819
          20212223242526
          27282930123
          45678910

          導(dǎo)航

          統(tǒng)計(jì)

          公告

          主要記錄作者在學(xué)習(xí)java中的每一步足跡。除非特別說明,所有文章均為本blog作者原創(chuàng),如需轉(zhuǎn)載請(qǐng)注明出處和原作者,如用于商業(yè)目的,需跟作者本人聯(lián)系。
          歡迎大家訪問:

          常用鏈接

          留言簿(16)

          隨筆分類

          隨筆檔案

          文章分類

          文章檔案

          相冊(cè)

          收藏夾

          java技術(shù)

          人間百態(tài)

          朋友們的blog

          搜索

          最新評(píng)論

          閱讀排行榜

          評(píng)論排行榜

          主站蜘蛛池模板: 云龙县| 马边| 铅山县| 鹿邑县| 裕民县| 梅河口市| 盈江县| 武邑县| 东乡县| 丰城市| 巍山| 景泰县| 彭州市| 德庆县| 婺源县| 沿河| 烟台市| 邯郸县| 沅江市| 禄丰县| 饶河县| 神农架林区| 台江县| 南宫市| 龙南县| 资溪县| 砚山县| 曲松县| 北京市| 遂昌县| 弋阳县| 开化县| 新化县| 鹤庆县| 普安县| 兴山县| 闽清县| 手游| 镇宁| 崇左市| 利辛县|