1.不要使用自動綁定
?? Spring 可以通過類的自省來自動綁定其從屬部分,使得你不必明確指明bean的屬性和構造器。Bean的屬性可以通過屬性名稱或類型匹配來實現自動綁定。構造器通過類型匹配來實現自動綁定。你甚至可以指定自動檢測自動綁定模式,它可以引導Spring選擇一種適當的運行機制。先來思考下面的一個例子:






????OrderService
類的屬性名在容器中用于匹配bean實例。自動綁定可以潛在地節省一些打字和減少一些混亂。但是在現實世界的工程里你不應該使用這種方式,這是因為它犧牲了配置的清晰性和可維護性。許多指南和介紹中大量吹捧自動綁定是Spring的一種極好的特征而沒有提到這一特性所帶來的犧牲。依我的觀點,這就像Spring中的object-pooling,它更像是一種 商業特征 。它對于XML配置文件的小巧化是一個好辦法,但實際上也增加了復雜程度,尤其當你運行有大量類聲明的工程時。雖然Spring允許你混合自動綁定和手動綁定,但是這個矛盾會使XML配置更加晦澀難懂。2.使用通俗的命名
??? 這個方式對于Java編碼也一樣適用。在工程中使用清晰的、描述性的、協調的通俗名稱對于開發者理解XML配置是十分有益的。例如對于bean ID,你可以根據通俗的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>
can be rewritten in the shortcut form as:
可以使用簡潔形式將上述代碼重寫為:
??? <bean id="orderService"
??????? class="com.lizjason.spring.OrderService">
??????? <property name="companyName"
??????????? value="lizjason"/>
??????? <constructor-arg ref="orderDAO"/>
??? </bean>
??? 簡潔形式功能在1.2版本中可以使用。對于<ref local="...">沒有簡潔形式。
??? 簡潔形式不但可以節約你的打字,而且可以使XML配置文件清晰。它最引人注目的是當在一個配置文件中有大量定義的類時可以提高易讀性。
??? 當一個構造器含有一個以上的同種類型的
條目
或者屬性值的標簽已經被占用時,Spring允許你使用從0計數的序號來解決這些不明確的問題。例如:
??? <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>
??? 使用索引可以稍稍減少一些冗長,但是和使用類型屬性相比,它還是有容易發生錯誤的傾向和難于閱讀的缺點。你應該只有在
構造器條目
不明確的時候,才使用索引這一方法。
5. 如果可能, 可以繼承已定義過的bean
????Spring
提供一種像繼承一樣的機制來減少配置信息的復制并簡化XML配置。定義一個子類可以從它父類那里繼承配置信息,而父類實質上作為子類的一個模板。這就是大工程中所謂的重用。你所需要做的就是抽象并真實地說明父類和子類中父類的
參數
。例如:
??? <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>
???? 但是,使用引用在XML配置中來預裝配他們已經不用了,而是通過ApplicationContext來配置他們,這樣顯得更加靈活。利用ApplicationContext也使得XML配置易于管理。你可以像下面的例子那樣在ApplictionContext構造器里布置bean:
??? String[] serviceResources =
??????? {"orderServices.xml",
??????? "billingServices.xml",
??????? "shippingServices.xml"};
??? ApplicationContext orderServiceContext = new
??????? ClassPathXmlApplicationContext(serviceResources);
|
7.
利用id作為bean的標識符
??? 你可以指定一個id或名稱來作為bean的標識符。雖然使用id不會提高易讀性,但是它在XML剖析器對bean參考有效方面起到了平衡的作用。如果由于XML IDREF容器的原因不能使用id,你可以利用名稱來作為bean的標識符。XML IDREF容器的原則使id必須以字母開頭(或者定義在XML規范中的標點符號),后面接著字母,數字,連字號,下劃線,冒號或者
句號
。在現實中,遇到XML IDREF容器問題是很少見的。
8. 在開發階段使用從屬檢測
??? 你可以在一定的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設置的屬性不是原始的 。它可能為所有的bean設置默認的從屬檢測,但是這個特性很少使用,是因為有些bean的屬性不必設置。
9. 為每個配置文件加上一個標題注釋
?? 首選descriptive id和名稱來代替在XML配置文件中的注釋。此外,加上一個配置文件標題很有用處,它可以概述文件中所定義的bean。你可以選擇將descpription(的內容)加入description標簽中。例如:




















??? 使用description標簽的一個好處是可以容易地利用工具從標簽中選取出description(的內容)。
10.對于變化變更,要與隊友積極交流
??? 當你重構Java代碼時,你需要隨時更新配置文件并且通知隊友。XML配置文件也是代碼,它們是應用程序的至關重要的部分,但是它們難于閱讀和維護。大部分時間你既要閱讀XML配置文件又要閱讀運行中的Java代碼。
11.Setter injection (鑲嵌注入)優于 constructor injection (構造器注入)
??? Spring
提供3種類型的從屬注入: constructor injectio(構造器注入),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不能在一個非法聲明下創建,但是setter injection(鑲嵌注入)更加靈活并且更易管理,尤其當類存在復合屬性并且屬性中的一些是可選的。
12. 不要濫用從屬注入
作為最后一點,Spring ApplicationContext可以替你創建Java對象,但是并不是所有的Java對象都通過從屬注入來創建的。例如,全局的對象不應該通過ApplicationContext來創建。Spring是一個很棒的框架,但是,就易讀性和易管理性而言,當定義大量bean的時候,基于XML的配置問題就會突出。過度的從屬注入會使XML配置變得復雜而且臃腫。記住!在強大的IDE時,例如Eclipse和IntelliJ,與XML文件相比,Java代碼更加易讀,易維護,易管理。
總結
??? 對于Spring的配置,XML是很流行的形式。但當定義大量bean時,基于XML配置會變得冗長,笨拙。Spring提供了豐富的配置選項。適當地利用其中的選項可以使XML配置清晰,但是,有些選項,例如autowiring(自動綁定),往往會降低易讀性和易維護性。文章中所列舉的實例,可以幫助你創建出清晰易讀的XML配置文件。
關于作者:
Jason Zhicheng Li
是Object Computing, Inc. in