posts - 189,comments - 115,trackbacks - 0
          轉貼]Spring?XML配置十二個最佳實踐

          轉自:http://www.javaresearch.org?? JAVA Research

          摘要:
          在這篇文章里,對于Spring?XML的配置,我將向你展示12種比較好的實踐。其中的一些實踐不僅是好的實踐,更是必要的實踐。除此以外,還有其他因素,例如領域模型的設計,都能影響XML的配置,但是這篇文章重點研究XML配置的易讀性和易管理性。

          Spring是一個強大的JAVA應用框架,廣泛地應用于JAVA的應用程序。為Plain?Old?Java?Objects(POJOs)提供企業(yè)級服務。Spring利用依賴注入機制來簡化工作,同時提高易測性。Spring?beans及依賴,以及beans類所需的服務都在配置文件中進行了詳細的說明,這個配置文件是典型的XML格式。但是它既冗長又不實用。對于需要定義大量Spring?beans的大工程來說,我們難以閱讀和管理它。

          版權聲明:任何獲得Matrix授權的網(wǎng)站,轉載時請務必保留以下作者信息和鏈接
          作者:Jason;Li;evenbetter(作者的blog:http://blog.matrix.org.cn/page/evenbetter)
          原文:http://www.onjava.com/pub/a/onjava/2006/01/25/spring-xml-configuration-best-practices.html
          譯文:http://www.matrix.org.cn/resource/article/44/44236_Spring+XML+Configurations.html
          關鍵字:Spring;XML;Configurations

          在這篇文章里,對于Spring?XML的配置,我將向你展示12種比較好的實踐。其中的一些實踐不僅是好的實踐,更是必要的實踐。除此以外,還有其他因素,例如領域模型的設計,都能影響XML的配置,但是這篇文章重點研究XML配置的易讀性和易管理性。

          1。不要使用autowiring

          Spring?可以通過類的自省來自動綁定其依賴部分,使得你不必明確指明bean的屬性和構造器。Bean的屬性可以通過屬性名稱或類型匹配來實現(xiàn)自動綁定。構造器通過類型匹配來實現(xiàn)自動綁定。你甚至可以指定自動檢測自動綁定模式,它可以引導Spring選擇一種適當?shù)倪\行機制。先來看看下面的一個例子:

          ????<bean?id="orderService"
          ????????class="com.lizjason.spring.OrderService"
          ????????autowire="byName"/>



          OrderService?類的屬性名在容器中用于匹配bean實例。自動綁定可以潛在地節(jié)省一些打字和減少一些混亂。但是在現(xiàn)實世界的工程里你不應該使用這種方式,這是因為它犧牲了配置的清晰性和可維護性。許多指南和介紹中大量吹捧自動綁定是Spring的一種極好的特征而沒有提到這一特性所帶來的犧牲。依我的觀點,這就像?Spring中的object-pooling,它更像是一種為了占據(jù)更多市場的商業(yè)特征。它對于XML配置文件的小巧化是一個好辦法,但實際上也增加了復雜程度,尤其當你運行有大量類聲明的工程時。雖然Spring允許你混合自動綁定和手動綁定,但是這個矛盾會使XML配置更加晦澀難懂。

          2.使用通俗的命名

          這個方式對于Java編碼也一樣適用。在工程中使用清晰的、描述性的、協(xié)調(diào)的通俗名稱對于開發(fā)者理解XML配置是十分有益的。例如對于bean?ID,你可以根據(jù)通俗的Java類名來命名它。對于例子中OrderServiceDAO的bean?ID命名為orderServiceDAO。對于大的工程,你可以在bean?ID前面加上包名作為前綴。

          3.?使用簡潔的形式

          簡潔形式避免了冗長,是因為它從子元素中將屬性值和參考寫到屬性中。例如下面的例子:

          ????<bean?id="orderService"
          ????????class="com.lizjason.spring.OrderService">
          ????????<property?name="companyName">
          ????????????<value>lizjason</value>
          ????????</property>
          ????????<constructor-arg>
          ????????????<ref?bean="orderDAO">
          ????????</constructor-arg>
          ????</bean>



          可以使用簡潔形式將上述代碼重寫為:

          ????<bean?id="orderService"
          ????????class="com.lizjason.spring.OrderService">
          ????????<property?name="companyName"
          ????????????value="/lizjason"/>
          ????????<constructor-arg?ref="orderDAO"/>
          ????</bean>



          簡潔形式功能在1.2版本中可以使用。對于<ref?local="...">沒有簡潔形式。
          簡潔形式不但可以節(jié)約你的打字,而且可以使XML配置文件清晰。它最引人注目的是當在一個配置文件中有大量定義的類時可以提高易讀性。

          4.?對于構造器參數(shù)匹配,類型名比序號好。

          當一個構造器含有一個以上的同種類型的參數(shù),或者屬性值的標簽已經(jīng)被占用時,Spring允許你使用從0計數(shù)的序號來解決這些會帶來混淆的問題。例如:

          ????<bean?id="billingService"
          ????????class="com.lizjason.spring.BillingService">
          ????????<constructor-arg?index="0"?value="lizjason"/>
          ????????<constructor-arg?index="1"?value="100"/>
          ????</bean>



          像下面這樣,利用類型屬性來編寫會更好一些:

          ????<bean?id="billingService"
          ????????class="com.lizjason.spring.BillingService">
          ????????<constructor-arg?type="java.lang.String"
          ????????????value="lizjason"/>
          ????????<constructor-arg?type="int"?value="100"/>
          ????</bean>



          使用索引可以稍稍減少一些冗長,但是和使用類型屬性相比,它還是有容易發(fā)生錯誤的傾向和難于閱讀的缺點。你應該只在構造器參數(shù)不明確的時候,才使用索引這一方法。

          5.?盡可能重用已定義過的bean

          Spring?提供一種類似繼承一樣的機制來減少配置信息的復制并簡化XML配置。定義一個子類可以從它父類那里繼承配置信息,而父類實質(zhì)上作為子類的一個模板。這就是大工程中所謂的重用。你所需要做的就是在父類bean中設置abstract=true,然后在子bean注明它自己的父類bean。例如:

          ????<bean?id="abstractService"?abstract="true"
          ????????class="com.lizjason.spring.AbstractService">
          ????????<property?name="companyName"
          ????????????value="lizjason"/>
          ????</bean>

          ????<bean?id="shippingService"
          ????????parent="abstractService"
          ????????class="com.lizjason.spring.ShippingService">
          ????????<property?name="shippedBy"?value="lizjason"/>
          ????</bean>




          ShippingService類從abstractService類那里繼承companyName屬性的值??lizjason。如果你沒有為一個bean指明類或factory方法,那么這個bean便是抽象的。

          6.?盡量使用ApplicationContext來裝配定義的bean

          像在Ant腳本中的引用一樣,Spring的引用對于裝配模塊化的bean來說是很有用的。例如:

          ????<beans>
          ????????<import?resource="billingServices.xml"/>
          ????????<import?resource="shippingServices.xml"/>
          ????????<bean?id="orderService"
          ????????????class="com.lizjason.spring.OrderService"/>
          ????<beans>



          相對于使用import在XML配置中來預裝配,通過ApplicationContext來配置這些beans,顯得更加靈活。利用?ApplicationContext也使得XML配置易于管理。你可以像下面的例子那樣在ApplictionContext構造器里布置bean:

          ????String[]?serviceResources?=
          ????????{"orderServices.xml",
          ????????"billingServices.xml",
          ????????"shippingServices.xml"};
          ????ApplicationContext?orderServiceContext?=?new
          ????????ClassPathXmlApplicationContext(serviceResources);


          ????????
          7.?利用id作為bean的標識符

          你可以指定一個id或名稱來作為bean的標識符。雖然使用id不會提高易讀性,但是它可以讓XML?parser對bean的引用有效方面進行更好的驗證。如果由于XML?IDREF的限制而不能使用某個id,你可以利用names來作為bean的標識符。XML?IDREF的限制是id必須以字母開頭(或者在XML規(guī)范中定義的標點符號),后面接著字母,數(shù)字,連字號,下劃線,冒號等。實際上,遇到XML?IDREF限制的問題是很少見的。

          8.?在開發(fā)階段使用依賴檢驗

          你可以在bean中給依賴檢驗的屬性設置值,而不采用原先默認的空值,屬性設置例如simple,object或all,以便容器進行依賴檢驗。當bean的全部的屬性(或某類屬性)需要被明確設置或自動綁定時,依賴檢驗便顯得很有用。

          ????<bean?id="orderService"
          ????????class="com.lizjason.spring.OrderService"
          ????????dependency-check="objects">
          ????????<property?name="companyName"
          ????????????value="lizjason"/>
          ????????<constructor-arg?ref="orderDAO"/>
          ????</bean>



          在這個例子里,容器確保為orderService?bean設置的屬性不是primitives?或者?collections。為所有的bean設置默認依賴檢測也是可以的,但是我們很少這樣做,是因為有些bean的屬性根本就不必設置。

          9.?為每個配置文件加上一個header?comment

          最好使用descriptive?id和名稱來代替在XML配置文件中的注釋。此外,加上一個配置文件header也很有用處,它可以概述文件中所定義的bean。你可以選擇將描述內(nèi)容加入description標簽中。例如:

          ????<beans>
          ????????<description>
          ????????????This?file?defines?billing?service
          ????????????related?beans?and?it?depends?on
          ????????????baseServices.xml,which?provides
          ????????????service?bean?templates...
          ????????</description>
          ????????...
          ????</beans>


          使用description標簽的一個好處是可以容易地利用工具從標簽中選取出description(的內(nèi)容)。

          10.?對于任何變化,要與隊友積極交流
          當你重構Java代碼時,你需要隨時更新配置文件并且通知隊友。XML配置文件也是代碼,它們是應用程序的至關重要的部分,但是它們難于閱讀和維護。大部分時間你既要閱讀XML配置文件又要閱讀運行中的Java代碼。

          11.?Setter?injection優(yōu)于constructor?injection

          Spring提供3種類型的依賴注入:?constructor?injection,setter?injection,?和method?injection。我們一般只用前兩種類型。

          ????<bean?id="orderService"
          ????????class="com.lizjason.spring.OrderService">
          ????????<constructor-arg?ref="orderDAO"/>
          ????</bean>

          ????<bean?id="billingService"
          ????????class="com.lizjason.spring.BillingService">
          ????????<property?name="billingDAO"
          ????????????ref="billingDAO">
          ????</bean>



          這個例子中,orderService類使用的是constructor?injection,而BillingService類使用的是setter?injection。constructor?injection可以確保bean不會在一個非法狀態(tài)下被創(chuàng)建,但是setter?injection更加靈活并且更易管理,尤其當類存在很多屬性并且其中一些是可選的情況下。

          12.?不要濫用依賴注入

          作為最后一點,Spring?ApplicationContext可以替你創(chuàng)建Java對象,但是并不是所有的Java對象都通過依賴注入來創(chuàng)建的。例如,全局的對象不應該通過?ApplicationContext來創(chuàng)建。Spring是一個很棒的框架,但是,就易讀性和易管理性而言,當定義大量bean的時候,基于XML的配置問題就會突出。過度的依賴注入會使XML配置變得復雜而且臃腫。記住!使用強大的IDE時,例如Eclipse和IntelliJ,與XML文件相比,?Java代碼更加易讀,易維護,易管理。

          總結
          對于Spring的配置,XML是很優(yōu)秀的方式。但當定義大量?bean時,基于XML配置會變得冗長,笨拙。Spring提供了豐富的配置選項。適當?shù)乩闷渲械倪x項可以使XML配置清晰,但是,有些選項,例如?autowiring(自動綁定),往往會降低易讀性和易維護性。文章中所列舉的實例,可以幫助你創(chuàng)建出清晰易讀的XML配置文件。

          ?

          posted on 2006-03-31 12:40 MEYE 閱讀(448) 評論(0)  編輯  收藏 所屬分類: Study
          主站蜘蛛池模板: 湘潭市| 六盘水市| 丰县| 皋兰县| 静安区| 葵青区| 大理市| 固始县| 连平县| 谷城县| 全椒县| 日喀则市| 黎川县| 翁源县| 吉林市| 日土县| 蓬安县| 永康市| 布尔津县| 麦盖提县| 浑源县| 沿河| 临江市| 云霄县| 铜梁县| 嵩明县| 岫岩| 成安县| 九台市| 永吉县| 滕州市| 泰安市| 菏泽市| 莱阳市| 乌拉特前旗| 明星| 大城县| 恭城| 广东省| 仙居县| 绥阳县|