Spring+hibernate實(shí)戰(zhàn)(二)
項(xiàng)目很小,主體部分也完成的差不多了,但麻雀雖小,五臟具全,我在其中用到了spring的IoC和transaction管理,也用到了簡(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ì)越來越多,不便于管理。于是我們通過配置如

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





< SPAN>bean>這是聲明一個(gè)Message對(duì)象實(shí)例的配置文件,${mail.from}表明是在*.properties文件配置的值,看到這個(gè)我們就知道SimpleMailMessage是一個(gè)具體類,有一個(gè)from的屬性,同時(shí)有一個(gè)setFrom的公共方法。Spring的ContextLoader在啟動(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)類。








講一個(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,我們就有了新的選擇。先看下面的配置文件:



















為簡(jiǎn)單起見,我沒有使用接口,直接定義了一個(gè)Auditer類,它有一個(gè)List類型的auditers屬性,然后加個(gè)set方法。對(duì)auditers里面的值,就使用spring支持的list配置方式進(jìn)行注入。你可以配多個(gè)value,contextLoader啟動(dòng)時(shí)就會(huì)自動(dòng)把這些value填入一個(gè)ArrayList實(shí)現(xiàn),然后set到auditer類中,你就可以直接使用這個(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的聲明式配置。






















以上配置文件就是定義了一個(gè)baseTransactionProxy 對(duì)象,它注入一個(gè)transactionManager對(duì)象,并注入一個(gè)transactionAttributes的Properties對(duì)象,這個(gè)Properties對(duì)象的配置就是

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

,這里很方便就能切換到另一種transactionManager的實(shí)現(xiàn)上去。PROPAGATION_REQUIRED表明會(huì)放入當(dāng)前的事務(wù)中,如果沒有就創(chuàng)建一個(gè)。Readonly表明此方法只讀,能提高速度,spring還支持隔離級(jí)別的配置,具體配置說明,可以看spring的api文檔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)書籍。


























有了spring的transaction管理,聲明式事務(wù)就不再是EJB所獨(dú)有了,我們可以使用spring的事務(wù),而避免僅僅因?yàn)橐暶魇绞聞?wù)而使用EJB這樣重量級(jí)的東西了。
先寫到這里吧,下篇我再繼續(xù)AOP和spring mvc的討論。
posted on 2005-11-07 16:02 pesome 閱讀(2559) 評(píng)論(0) 編輯 收藏 所屬分類: Spring+Struts+Hibernate