'架構師成長之路-Java程序員必須掌握Spring XML配置的12個技巧'

XML Java 程序員 設計 文章 JAVA大飛哥 2019-07-20
"
"
架構師成長之路-Java程序員必須掌握Spring XML配置的12個技巧

引言

Spring是一個強有力的Java程序框架,其被廣泛應用於Java的程序中。它用POJO提供了企業級服務。Spring利用依賴注入可以獲得簡單而有效的測試能力。Spring beans,依賴關係,以及服務所需要的bean都將在配置文件中予以描述,配置文件一般採用XML格式。然而XML配置文件冗長而不易使用,在你進行一個使用了大量bean的大項目中它將變得難以閱讀和控制。

在這篇文章中我將給你展示12種的有關Spring XML配置文件的最佳技巧。它們中的一些具有更多的實際意義,而不僅是最好的技巧。請注意另外一些因素,例如域模型的設計,會影響到XML配置,但是這篇文章更關注於XML配置的可讀性和可操控性。

1. 避免使用自動裝配

Spring可以通過bean類的自省來實現自動裝配依賴,這樣的話你就不必明確地描述bean的屬性或者構造函數的參數。根據屬性名稱活匹配類型,bean屬性可以自動進行裝配。而構造函數可以根據匹配類型自動裝配。你甚至可以設置自動裝配進行自動偵測,這樣Spring替你就會選擇一個合適的機制。請看下面的例子:

Spring可以通過bean類的自省來實現自動裝配依賴,這樣的話你就不必明確地描述bean的屬性或者構造函數的參數。根據屬性名稱活匹配類型,bean屬性可以自動進行裝配。而構造函數可以根據匹配類型自動裝配。你甚至可以設置自動裝配進行自動偵測,這樣Spring替你就會選擇一個合適的機制。請看下面的例子:

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

OrderService類的屬性名被用來和容器中的一個bean實例進行匹配。自動裝配會默默的保存一些類型信息並降低混亂。然而,由於它會犧牲掉這種配置的直觀性和可維護性,你在實際的項目中將不會用到它。許多指南和陳述材料都把它吹捧為Spring的一個非常cool的特性,而沒有提到它的這個缺點。依我之見,就像Spring的對象池一樣,它更多了一些商業味道。它看起來好像可以使XML配置文件更精簡一些,但實際上卻增加其複雜性,尤其是在你的較大規模的工程中已經定義了很多bean的時候更是如此。Spring允許你混合使用自動和手動裝配,但是這種矛盾會使XML配置更加的令人費解。

2. 使用命名規範

和Java編碼的理念一樣,在項目中始終用清晰的,描述性的,一致的命名規範對開發人員理解XML配置非常有用。拿bean ID舉例來說,你可以遵循Java類中屬性的命名規範。比如說,OrderServiceDAO的bean ID應該是orderServiceDAO。對於大項目來說,在bean ID前加包名來作為前綴。

3. 使用簡化格式

簡化格式有利於減少冗餘,因為它把屬性值和引用作為屬性,而不是子元素。看下面的例子:

"
架構師成長之路-Java程序員必須掌握Spring XML配置的12個技巧

引言

Spring是一個強有力的Java程序框架,其被廣泛應用於Java的程序中。它用POJO提供了企業級服務。Spring利用依賴注入可以獲得簡單而有效的測試能力。Spring beans,依賴關係,以及服務所需要的bean都將在配置文件中予以描述,配置文件一般採用XML格式。然而XML配置文件冗長而不易使用,在你進行一個使用了大量bean的大項目中它將變得難以閱讀和控制。

在這篇文章中我將給你展示12種的有關Spring XML配置文件的最佳技巧。它們中的一些具有更多的實際意義,而不僅是最好的技巧。請注意另外一些因素,例如域模型的設計,會影響到XML配置,但是這篇文章更關注於XML配置的可讀性和可操控性。

1. 避免使用自動裝配

Spring可以通過bean類的自省來實現自動裝配依賴,這樣的話你就不必明確地描述bean的屬性或者構造函數的參數。根據屬性名稱活匹配類型,bean屬性可以自動進行裝配。而構造函數可以根據匹配類型自動裝配。你甚至可以設置自動裝配進行自動偵測,這樣Spring替你就會選擇一個合適的機制。請看下面的例子:

Spring可以通過bean類的自省來實現自動裝配依賴,這樣的話你就不必明確地描述bean的屬性或者構造函數的參數。根據屬性名稱活匹配類型,bean屬性可以自動進行裝配。而構造函數可以根據匹配類型自動裝配。你甚至可以設置自動裝配進行自動偵測,這樣Spring替你就會選擇一個合適的機制。請看下面的例子:

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

OrderService類的屬性名被用來和容器中的一個bean實例進行匹配。自動裝配會默默的保存一些類型信息並降低混亂。然而,由於它會犧牲掉這種配置的直觀性和可維護性,你在實際的項目中將不會用到它。許多指南和陳述材料都把它吹捧為Spring的一個非常cool的特性,而沒有提到它的這個缺點。依我之見,就像Spring的對象池一樣,它更多了一些商業味道。它看起來好像可以使XML配置文件更精簡一些,但實際上卻增加其複雜性,尤其是在你的較大規模的工程中已經定義了很多bean的時候更是如此。Spring允許你混合使用自動和手動裝配,但是這種矛盾會使XML配置更加的令人費解。

2. 使用命名規範

和Java編碼的理念一樣,在項目中始終用清晰的,描述性的,一致的命名規範對開發人員理解XML配置非常有用。拿bean ID舉例來說,你可以遵循Java類中屬性的命名規範。比如說,OrderServiceDAO的bean ID應該是orderServiceDAO。對於大項目來說,在bean ID前加包名來作為前綴。

3. 使用簡化格式

簡化格式有利於減少冗餘,因為它把屬性值和引用作為屬性,而不是子元素。看下面的例子:

架構師成長之路-Java程序員必須掌握Spring XML配置的12個技巧

<bean id="orderService"
class="com.lizjason.spring.OrderService">
<property name="companyName">
<value>lizjason</value>
</property>
<constructor-arg>
<ref bean="orderDAO">
</constructor-arg>
</bean>
"
架構師成長之路-Java程序員必須掌握Spring XML配置的12個技巧

引言

Spring是一個強有力的Java程序框架,其被廣泛應用於Java的程序中。它用POJO提供了企業級服務。Spring利用依賴注入可以獲得簡單而有效的測試能力。Spring beans,依賴關係,以及服務所需要的bean都將在配置文件中予以描述,配置文件一般採用XML格式。然而XML配置文件冗長而不易使用,在你進行一個使用了大量bean的大項目中它將變得難以閱讀和控制。

在這篇文章中我將給你展示12種的有關Spring XML配置文件的最佳技巧。它們中的一些具有更多的實際意義,而不僅是最好的技巧。請注意另外一些因素,例如域模型的設計,會影響到XML配置,但是這篇文章更關注於XML配置的可讀性和可操控性。

1. 避免使用自動裝配

Spring可以通過bean類的自省來實現自動裝配依賴,這樣的話你就不必明確地描述bean的屬性或者構造函數的參數。根據屬性名稱活匹配類型,bean屬性可以自動進行裝配。而構造函數可以根據匹配類型自動裝配。你甚至可以設置自動裝配進行自動偵測,這樣Spring替你就會選擇一個合適的機制。請看下面的例子:

Spring可以通過bean類的自省來實現自動裝配依賴,這樣的話你就不必明確地描述bean的屬性或者構造函數的參數。根據屬性名稱活匹配類型,bean屬性可以自動進行裝配。而構造函數可以根據匹配類型自動裝配。你甚至可以設置自動裝配進行自動偵測,這樣Spring替你就會選擇一個合適的機制。請看下面的例子:

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

OrderService類的屬性名被用來和容器中的一個bean實例進行匹配。自動裝配會默默的保存一些類型信息並降低混亂。然而,由於它會犧牲掉這種配置的直觀性和可維護性,你在實際的項目中將不會用到它。許多指南和陳述材料都把它吹捧為Spring的一個非常cool的特性,而沒有提到它的這個缺點。依我之見,就像Spring的對象池一樣,它更多了一些商業味道。它看起來好像可以使XML配置文件更精簡一些,但實際上卻增加其複雜性,尤其是在你的較大規模的工程中已經定義了很多bean的時候更是如此。Spring允許你混合使用自動和手動裝配,但是這種矛盾會使XML配置更加的令人費解。

2. 使用命名規範

和Java編碼的理念一樣,在項目中始終用清晰的,描述性的,一致的命名規範對開發人員理解XML配置非常有用。拿bean ID舉例來說,你可以遵循Java類中屬性的命名規範。比如說,OrderServiceDAO的bean ID應該是orderServiceDAO。對於大項目來說,在bean ID前加包名來作為前綴。

3. 使用簡化格式

簡化格式有利於減少冗餘,因為它把屬性值和引用作為屬性,而不是子元素。看下面的例子:

架構師成長之路-Java程序員必須掌握Spring XML配置的12個技巧

<bean id="orderService"
class="com.lizjason.spring.OrderService">
<property name="companyName">
<value>lizjason</value>
</property>
<constructor-arg>
<ref bean="orderDAO">
</constructor-arg>
</bean>
架構師成長之路-Java程序員必須掌握Spring XML配置的12個技巧

以上程序可以重新以簡化格式書寫為:

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

簡化格式在1.2版本時已經可用了,但請注意不存在<ref local="...">這種簡化格式不僅可以較少你的代碼輸入量,而且可以使XML配置更加的清晰。當你的配置文件中存在大量的bean定義時,它可以顯著地提高可讀性。

4. 儘量使用type而不是index去解決構造函數參數的匹配問題

當構造函數中有多個同類型的參數時,Spring只允許你使用從0開始的index或者value標籤來解決這個問題。請看下面的例子:

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

最好用type屬性取代上面的做法:

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

用index可以稍微減少冗餘,但是它更容易出錯且不如type屬性可讀性高。你應該僅在構造函數中有參數衝突時使用index。

5. 如可能,儘量複用bean定義

Spring提供了一種類似於繼承的機制來降低配置信息的重複並使XML配置更加的簡單。一個子bean可以從它的父bean繼承配置信息,本質上這個父bean就像它的子bean的一個模板。這是一個在大型項目中必須使用的特性。所有你要做的就是把父bean的abstract屬性置為true,並在子bean中加以引用。例如:

"
架構師成長之路-Java程序員必須掌握Spring XML配置的12個技巧

引言

Spring是一個強有力的Java程序框架,其被廣泛應用於Java的程序中。它用POJO提供了企業級服務。Spring利用依賴注入可以獲得簡單而有效的測試能力。Spring beans,依賴關係,以及服務所需要的bean都將在配置文件中予以描述,配置文件一般採用XML格式。然而XML配置文件冗長而不易使用,在你進行一個使用了大量bean的大項目中它將變得難以閱讀和控制。

在這篇文章中我將給你展示12種的有關Spring XML配置文件的最佳技巧。它們中的一些具有更多的實際意義,而不僅是最好的技巧。請注意另外一些因素,例如域模型的設計,會影響到XML配置,但是這篇文章更關注於XML配置的可讀性和可操控性。

1. 避免使用自動裝配

Spring可以通過bean類的自省來實現自動裝配依賴,這樣的話你就不必明確地描述bean的屬性或者構造函數的參數。根據屬性名稱活匹配類型,bean屬性可以自動進行裝配。而構造函數可以根據匹配類型自動裝配。你甚至可以設置自動裝配進行自動偵測,這樣Spring替你就會選擇一個合適的機制。請看下面的例子:

Spring可以通過bean類的自省來實現自動裝配依賴,這樣的話你就不必明確地描述bean的屬性或者構造函數的參數。根據屬性名稱活匹配類型,bean屬性可以自動進行裝配。而構造函數可以根據匹配類型自動裝配。你甚至可以設置自動裝配進行自動偵測,這樣Spring替你就會選擇一個合適的機制。請看下面的例子:

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

OrderService類的屬性名被用來和容器中的一個bean實例進行匹配。自動裝配會默默的保存一些類型信息並降低混亂。然而,由於它會犧牲掉這種配置的直觀性和可維護性,你在實際的項目中將不會用到它。許多指南和陳述材料都把它吹捧為Spring的一個非常cool的特性,而沒有提到它的這個缺點。依我之見,就像Spring的對象池一樣,它更多了一些商業味道。它看起來好像可以使XML配置文件更精簡一些,但實際上卻增加其複雜性,尤其是在你的較大規模的工程中已經定義了很多bean的時候更是如此。Spring允許你混合使用自動和手動裝配,但是這種矛盾會使XML配置更加的令人費解。

2. 使用命名規範

和Java編碼的理念一樣,在項目中始終用清晰的,描述性的,一致的命名規範對開發人員理解XML配置非常有用。拿bean ID舉例來說,你可以遵循Java類中屬性的命名規範。比如說,OrderServiceDAO的bean ID應該是orderServiceDAO。對於大項目來說,在bean ID前加包名來作為前綴。

3. 使用簡化格式

簡化格式有利於減少冗餘,因為它把屬性值和引用作為屬性,而不是子元素。看下面的例子:

架構師成長之路-Java程序員必須掌握Spring XML配置的12個技巧

<bean id="orderService"
class="com.lizjason.spring.OrderService">
<property name="companyName">
<value>lizjason</value>
</property>
<constructor-arg>
<ref bean="orderDAO">
</constructor-arg>
</bean>
架構師成長之路-Java程序員必須掌握Spring XML配置的12個技巧

以上程序可以重新以簡化格式書寫為:

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

簡化格式在1.2版本時已經可用了,但請注意不存在<ref local="...">這種簡化格式不僅可以較少你的代碼輸入量,而且可以使XML配置更加的清晰。當你的配置文件中存在大量的bean定義時,它可以顯著地提高可讀性。

4. 儘量使用type而不是index去解決構造函數參數的匹配問題

當構造函數中有多個同類型的參數時,Spring只允許你使用從0開始的index或者value標籤來解決這個問題。請看下面的例子:

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

最好用type屬性取代上面的做法:

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

用index可以稍微減少冗餘,但是它更容易出錯且不如type屬性可讀性高。你應該僅在構造函數中有參數衝突時使用index。

5. 如可能,儘量複用bean定義

Spring提供了一種類似於繼承的機制來降低配置信息的重複並使XML配置更加的簡單。一個子bean可以從它的父bean繼承配置信息,本質上這個父bean就像它的子bean的一個模板。這是一個在大型項目中必須使用的特性。所有你要做的就是把父bean的abstract屬性置為true,並在子bean中加以引用。例如:

架構師成長之路-Java程序員必須掌握Spring XML配置的12個技巧

<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>
"
架構師成長之路-Java程序員必須掌握Spring XML配置的12個技巧

引言

Spring是一個強有力的Java程序框架,其被廣泛應用於Java的程序中。它用POJO提供了企業級服務。Spring利用依賴注入可以獲得簡單而有效的測試能力。Spring beans,依賴關係,以及服務所需要的bean都將在配置文件中予以描述,配置文件一般採用XML格式。然而XML配置文件冗長而不易使用,在你進行一個使用了大量bean的大項目中它將變得難以閱讀和控制。

在這篇文章中我將給你展示12種的有關Spring XML配置文件的最佳技巧。它們中的一些具有更多的實際意義,而不僅是最好的技巧。請注意另外一些因素,例如域模型的設計,會影響到XML配置,但是這篇文章更關注於XML配置的可讀性和可操控性。

1. 避免使用自動裝配

Spring可以通過bean類的自省來實現自動裝配依賴,這樣的話你就不必明確地描述bean的屬性或者構造函數的參數。根據屬性名稱活匹配類型,bean屬性可以自動進行裝配。而構造函數可以根據匹配類型自動裝配。你甚至可以設置自動裝配進行自動偵測,這樣Spring替你就會選擇一個合適的機制。請看下面的例子:

Spring可以通過bean類的自省來實現自動裝配依賴,這樣的話你就不必明確地描述bean的屬性或者構造函數的參數。根據屬性名稱活匹配類型,bean屬性可以自動進行裝配。而構造函數可以根據匹配類型自動裝配。你甚至可以設置自動裝配進行自動偵測,這樣Spring替你就會選擇一個合適的機制。請看下面的例子:

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

OrderService類的屬性名被用來和容器中的一個bean實例進行匹配。自動裝配會默默的保存一些類型信息並降低混亂。然而,由於它會犧牲掉這種配置的直觀性和可維護性,你在實際的項目中將不會用到它。許多指南和陳述材料都把它吹捧為Spring的一個非常cool的特性,而沒有提到它的這個缺點。依我之見,就像Spring的對象池一樣,它更多了一些商業味道。它看起來好像可以使XML配置文件更精簡一些,但實際上卻增加其複雜性,尤其是在你的較大規模的工程中已經定義了很多bean的時候更是如此。Spring允許你混合使用自動和手動裝配,但是這種矛盾會使XML配置更加的令人費解。

2. 使用命名規範

和Java編碼的理念一樣,在項目中始終用清晰的,描述性的,一致的命名規範對開發人員理解XML配置非常有用。拿bean ID舉例來說,你可以遵循Java類中屬性的命名規範。比如說,OrderServiceDAO的bean ID應該是orderServiceDAO。對於大項目來說,在bean ID前加包名來作為前綴。

3. 使用簡化格式

簡化格式有利於減少冗餘,因為它把屬性值和引用作為屬性,而不是子元素。看下面的例子:

架構師成長之路-Java程序員必須掌握Spring XML配置的12個技巧

<bean id="orderService"
class="com.lizjason.spring.OrderService">
<property name="companyName">
<value>lizjason</value>
</property>
<constructor-arg>
<ref bean="orderDAO">
</constructor-arg>
</bean>
架構師成長之路-Java程序員必須掌握Spring XML配置的12個技巧

以上程序可以重新以簡化格式書寫為:

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

簡化格式在1.2版本時已經可用了,但請注意不存在<ref local="...">這種簡化格式不僅可以較少你的代碼輸入量,而且可以使XML配置更加的清晰。當你的配置文件中存在大量的bean定義時,它可以顯著地提高可讀性。

4. 儘量使用type而不是index去解決構造函數參數的匹配問題

當構造函數中有多個同類型的參數時,Spring只允許你使用從0開始的index或者value標籤來解決這個問題。請看下面的例子:

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

最好用type屬性取代上面的做法:

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

用index可以稍微減少冗餘,但是它更容易出錯且不如type屬性可讀性高。你應該僅在構造函數中有參數衝突時使用index。

5. 如可能,儘量複用bean定義

Spring提供了一種類似於繼承的機制來降低配置信息的重複並使XML配置更加的簡單。一個子bean可以從它的父bean繼承配置信息,本質上這個父bean就像它的子bean的一個模板。這是一個在大型項目中必須使用的特性。所有你要做的就是把父bean的abstract屬性置為true,並在子bean中加以引用。例如:

架構師成長之路-Java程序員必須掌握Spring XML配置的12個技巧

<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>
架構師成長之路-Java程序員必須掌握Spring XML配置的12個技巧

shippingService bean繼承了abstractService bean的屬性companyName的值lizjason。注意,如果你為bean聲名一個class或工廠方法,這個bean將會默認為abstract

6. 儘量使用ApplicationContext裝配bean,而不是用import

像Ant腳本中imports一樣,Spring的import 元素對於模塊化bean的裝配非常有用,例如:

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

然而,比起在XML中用imports預裝配這些bean,利用ApplicationContext來配置它們將更加靈活,也可以使XML配置更加的易於管理。你可以像下面這樣傳遞一個bean定義數組到ApplicationContext的構造函數中:

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

7. 用id來標識bean

你可以用id或名字作為bean的標識。用id可讀性較差,但是它可以影響XML分析器使bean的reference有效。如果id由於XML IDREF約束而無法使用,你可以用name作為bean的標識。XML IDREF約束是指id必須以字母開始(或者是在XML聲名了的一個標點符號),後面可以是字母,數字,連字符,下劃線,冒號或full stops(不知道怎麼翻譯好)。在實際應用中很少會遇到XML IDREF約束問題。

8. 在開發階段使用依賴檢查

你可以為bean的dependency-check屬性設置一個值來取代默認的none,比如說simple,objects或者all,這樣的話容器將替你做依賴有效性的檢查。當一個bean的所有屬性(或者某些屬性目錄)都被明確設置,或利用自動裝配時將會非常有用。

"
架構師成長之路-Java程序員必須掌握Spring XML配置的12個技巧

引言

Spring是一個強有力的Java程序框架,其被廣泛應用於Java的程序中。它用POJO提供了企業級服務。Spring利用依賴注入可以獲得簡單而有效的測試能力。Spring beans,依賴關係,以及服務所需要的bean都將在配置文件中予以描述,配置文件一般採用XML格式。然而XML配置文件冗長而不易使用,在你進行一個使用了大量bean的大項目中它將變得難以閱讀和控制。

在這篇文章中我將給你展示12種的有關Spring XML配置文件的最佳技巧。它們中的一些具有更多的實際意義,而不僅是最好的技巧。請注意另外一些因素,例如域模型的設計,會影響到XML配置,但是這篇文章更關注於XML配置的可讀性和可操控性。

1. 避免使用自動裝配

Spring可以通過bean類的自省來實現自動裝配依賴,這樣的話你就不必明確地描述bean的屬性或者構造函數的參數。根據屬性名稱活匹配類型,bean屬性可以自動進行裝配。而構造函數可以根據匹配類型自動裝配。你甚至可以設置自動裝配進行自動偵測,這樣Spring替你就會選擇一個合適的機制。請看下面的例子:

Spring可以通過bean類的自省來實現自動裝配依賴,這樣的話你就不必明確地描述bean的屬性或者構造函數的參數。根據屬性名稱活匹配類型,bean屬性可以自動進行裝配。而構造函數可以根據匹配類型自動裝配。你甚至可以設置自動裝配進行自動偵測,這樣Spring替你就會選擇一個合適的機制。請看下面的例子:

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

OrderService類的屬性名被用來和容器中的一個bean實例進行匹配。自動裝配會默默的保存一些類型信息並降低混亂。然而,由於它會犧牲掉這種配置的直觀性和可維護性,你在實際的項目中將不會用到它。許多指南和陳述材料都把它吹捧為Spring的一個非常cool的特性,而沒有提到它的這個缺點。依我之見,就像Spring的對象池一樣,它更多了一些商業味道。它看起來好像可以使XML配置文件更精簡一些,但實際上卻增加其複雜性,尤其是在你的較大規模的工程中已經定義了很多bean的時候更是如此。Spring允許你混合使用自動和手動裝配,但是這種矛盾會使XML配置更加的令人費解。

2. 使用命名規範

和Java編碼的理念一樣,在項目中始終用清晰的,描述性的,一致的命名規範對開發人員理解XML配置非常有用。拿bean ID舉例來說,你可以遵循Java類中屬性的命名規範。比如說,OrderServiceDAO的bean ID應該是orderServiceDAO。對於大項目來說,在bean ID前加包名來作為前綴。

3. 使用簡化格式

簡化格式有利於減少冗餘,因為它把屬性值和引用作為屬性,而不是子元素。看下面的例子:

架構師成長之路-Java程序員必須掌握Spring XML配置的12個技巧

<bean id="orderService"
class="com.lizjason.spring.OrderService">
<property name="companyName">
<value>lizjason</value>
</property>
<constructor-arg>
<ref bean="orderDAO">
</constructor-arg>
</bean>
架構師成長之路-Java程序員必須掌握Spring XML配置的12個技巧

以上程序可以重新以簡化格式書寫為:

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

簡化格式在1.2版本時已經可用了,但請注意不存在<ref local="...">這種簡化格式不僅可以較少你的代碼輸入量,而且可以使XML配置更加的清晰。當你的配置文件中存在大量的bean定義時,它可以顯著地提高可讀性。

4. 儘量使用type而不是index去解決構造函數參數的匹配問題

當構造函數中有多個同類型的參數時,Spring只允許你使用從0開始的index或者value標籤來解決這個問題。請看下面的例子:

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

最好用type屬性取代上面的做法:

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

用index可以稍微減少冗餘,但是它更容易出錯且不如type屬性可讀性高。你應該僅在構造函數中有參數衝突時使用index。

5. 如可能,儘量複用bean定義

Spring提供了一種類似於繼承的機制來降低配置信息的重複並使XML配置更加的簡單。一個子bean可以從它的父bean繼承配置信息,本質上這個父bean就像它的子bean的一個模板。這是一個在大型項目中必須使用的特性。所有你要做的就是把父bean的abstract屬性置為true,並在子bean中加以引用。例如:

架構師成長之路-Java程序員必須掌握Spring XML配置的12個技巧

<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>
架構師成長之路-Java程序員必須掌握Spring XML配置的12個技巧

shippingService bean繼承了abstractService bean的屬性companyName的值lizjason。注意,如果你為bean聲名一個class或工廠方法,這個bean將會默認為abstract

6. 儘量使用ApplicationContext裝配bean,而不是用import

像Ant腳本中imports一樣,Spring的import 元素對於模塊化bean的裝配非常有用,例如:

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

然而,比起在XML中用imports預裝配這些bean,利用ApplicationContext來配置它們將更加靈活,也可以使XML配置更加的易於管理。你可以像下面這樣傳遞一個bean定義數組到ApplicationContext的構造函數中:

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

7. 用id來標識bean

你可以用id或名字作為bean的標識。用id可讀性較差,但是它可以影響XML分析器使bean的reference有效。如果id由於XML IDREF約束而無法使用,你可以用name作為bean的標識。XML IDREF約束是指id必須以字母開始(或者是在XML聲名了的一個標點符號),後面可以是字母,數字,連字符,下劃線,冒號或full stops(不知道怎麼翻譯好)。在實際應用中很少會遇到XML IDREF約束問題。

8. 在開發階段使用依賴檢查

你可以為bean的dependency-check屬性設置一個值來取代默認的none,比如說simple,objects或者all,這樣的話容器將替你做依賴有效性的檢查。當一個bean的所有屬性(或者某些屬性目錄)都被明確設置,或利用自動裝配時將會非常有用。

架構師成長之路-Java程序員必須掌握Spring XML配置的12個技巧

<bean id="orderService"
class="com.lizjason.spring.OrderService"
dependency-check="objects">
<property name="companyName"
value="lizjason"/>
<constructor-arg ref="orderDAO"/>
</bean>
"
架構師成長之路-Java程序員必須掌握Spring XML配置的12個技巧

引言

Spring是一個強有力的Java程序框架,其被廣泛應用於Java的程序中。它用POJO提供了企業級服務。Spring利用依賴注入可以獲得簡單而有效的測試能力。Spring beans,依賴關係,以及服務所需要的bean都將在配置文件中予以描述,配置文件一般採用XML格式。然而XML配置文件冗長而不易使用,在你進行一個使用了大量bean的大項目中它將變得難以閱讀和控制。

在這篇文章中我將給你展示12種的有關Spring XML配置文件的最佳技巧。它們中的一些具有更多的實際意義,而不僅是最好的技巧。請注意另外一些因素,例如域模型的設計,會影響到XML配置,但是這篇文章更關注於XML配置的可讀性和可操控性。

1. 避免使用自動裝配

Spring可以通過bean類的自省來實現自動裝配依賴,這樣的話你就不必明確地描述bean的屬性或者構造函數的參數。根據屬性名稱活匹配類型,bean屬性可以自動進行裝配。而構造函數可以根據匹配類型自動裝配。你甚至可以設置自動裝配進行自動偵測,這樣Spring替你就會選擇一個合適的機制。請看下面的例子:

Spring可以通過bean類的自省來實現自動裝配依賴,這樣的話你就不必明確地描述bean的屬性或者構造函數的參數。根據屬性名稱活匹配類型,bean屬性可以自動進行裝配。而構造函數可以根據匹配類型自動裝配。你甚至可以設置自動裝配進行自動偵測,這樣Spring替你就會選擇一個合適的機制。請看下面的例子:

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

OrderService類的屬性名被用來和容器中的一個bean實例進行匹配。自動裝配會默默的保存一些類型信息並降低混亂。然而,由於它會犧牲掉這種配置的直觀性和可維護性,你在實際的項目中將不會用到它。許多指南和陳述材料都把它吹捧為Spring的一個非常cool的特性,而沒有提到它的這個缺點。依我之見,就像Spring的對象池一樣,它更多了一些商業味道。它看起來好像可以使XML配置文件更精簡一些,但實際上卻增加其複雜性,尤其是在你的較大規模的工程中已經定義了很多bean的時候更是如此。Spring允許你混合使用自動和手動裝配,但是這種矛盾會使XML配置更加的令人費解。

2. 使用命名規範

和Java編碼的理念一樣,在項目中始終用清晰的,描述性的,一致的命名規範對開發人員理解XML配置非常有用。拿bean ID舉例來說,你可以遵循Java類中屬性的命名規範。比如說,OrderServiceDAO的bean ID應該是orderServiceDAO。對於大項目來說,在bean ID前加包名來作為前綴。

3. 使用簡化格式

簡化格式有利於減少冗餘,因為它把屬性值和引用作為屬性,而不是子元素。看下面的例子:

架構師成長之路-Java程序員必須掌握Spring XML配置的12個技巧

<bean id="orderService"
class="com.lizjason.spring.OrderService">
<property name="companyName">
<value>lizjason</value>
</property>
<constructor-arg>
<ref bean="orderDAO">
</constructor-arg>
</bean>
架構師成長之路-Java程序員必須掌握Spring XML配置的12個技巧

以上程序可以重新以簡化格式書寫為:

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

簡化格式在1.2版本時已經可用了,但請注意不存在<ref local="...">這種簡化格式不僅可以較少你的代碼輸入量,而且可以使XML配置更加的清晰。當你的配置文件中存在大量的bean定義時,它可以顯著地提高可讀性。

4. 儘量使用type而不是index去解決構造函數參數的匹配問題

當構造函數中有多個同類型的參數時,Spring只允許你使用從0開始的index或者value標籤來解決這個問題。請看下面的例子:

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

最好用type屬性取代上面的做法:

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

用index可以稍微減少冗餘,但是它更容易出錯且不如type屬性可讀性高。你應該僅在構造函數中有參數衝突時使用index。

5. 如可能,儘量複用bean定義

Spring提供了一種類似於繼承的機制來降低配置信息的重複並使XML配置更加的簡單。一個子bean可以從它的父bean繼承配置信息,本質上這個父bean就像它的子bean的一個模板。這是一個在大型項目中必須使用的特性。所有你要做的就是把父bean的abstract屬性置為true,並在子bean中加以引用。例如:

架構師成長之路-Java程序員必須掌握Spring XML配置的12個技巧

<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>
架構師成長之路-Java程序員必須掌握Spring XML配置的12個技巧

shippingService bean繼承了abstractService bean的屬性companyName的值lizjason。注意,如果你為bean聲名一個class或工廠方法,這個bean將會默認為abstract

6. 儘量使用ApplicationContext裝配bean,而不是用import

像Ant腳本中imports一樣,Spring的import 元素對於模塊化bean的裝配非常有用,例如:

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

然而,比起在XML中用imports預裝配這些bean,利用ApplicationContext來配置它們將更加靈活,也可以使XML配置更加的易於管理。你可以像下面這樣傳遞一個bean定義數組到ApplicationContext的構造函數中:

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

7. 用id來標識bean

你可以用id或名字作為bean的標識。用id可讀性較差,但是它可以影響XML分析器使bean的reference有效。如果id由於XML IDREF約束而無法使用,你可以用name作為bean的標識。XML IDREF約束是指id必須以字母開始(或者是在XML聲名了的一個標點符號),後面可以是字母,數字,連字符,下劃線,冒號或full stops(不知道怎麼翻譯好)。在實際應用中很少會遇到XML IDREF約束問題。

8. 在開發階段使用依賴檢查

你可以為bean的dependency-check屬性設置一個值來取代默認的none,比如說simple,objects或者all,這樣的話容器將替你做依賴有效性的檢查。當一個bean的所有屬性(或者某些屬性目錄)都被明確設置,或利用自動裝配時將會非常有用。

架構師成長之路-Java程序員必須掌握Spring XML配置的12個技巧

<bean id="orderService"
class="com.lizjason.spring.OrderService"
dependency-check="objects">
<property name="companyName"
value="lizjason"/>
<constructor-arg ref="orderDAO"/>
</bean>
架構師成長之路-Java程序員必須掌握Spring XML配置的12個技巧

在這個例子中,容器將確保這些屬性不是privitives或者保證collections是為orderService bean設置的。為所有的bean設置默認的依賴檢查是可能的,但這個特性由於有些bean的屬性不需要設置而很少使用。

9. 為每個配置文件加一個描述註釋

在XML配置文件中最好使用有描述性的id和name,而不是成堆的註釋。另外,加一個文件描述頭將會非常有用,這個描述可以概括文件中定義的bean。另一個選擇,你可以在description元素中加入描述信息。例如:

"
架構師成長之路-Java程序員必須掌握Spring XML配置的12個技巧

引言

Spring是一個強有力的Java程序框架,其被廣泛應用於Java的程序中。它用POJO提供了企業級服務。Spring利用依賴注入可以獲得簡單而有效的測試能力。Spring beans,依賴關係,以及服務所需要的bean都將在配置文件中予以描述,配置文件一般採用XML格式。然而XML配置文件冗長而不易使用,在你進行一個使用了大量bean的大項目中它將變得難以閱讀和控制。

在這篇文章中我將給你展示12種的有關Spring XML配置文件的最佳技巧。它們中的一些具有更多的實際意義,而不僅是最好的技巧。請注意另外一些因素,例如域模型的設計,會影響到XML配置,但是這篇文章更關注於XML配置的可讀性和可操控性。

1. 避免使用自動裝配

Spring可以通過bean類的自省來實現自動裝配依賴,這樣的話你就不必明確地描述bean的屬性或者構造函數的參數。根據屬性名稱活匹配類型,bean屬性可以自動進行裝配。而構造函數可以根據匹配類型自動裝配。你甚至可以設置自動裝配進行自動偵測,這樣Spring替你就會選擇一個合適的機制。請看下面的例子:

Spring可以通過bean類的自省來實現自動裝配依賴,這樣的話你就不必明確地描述bean的屬性或者構造函數的參數。根據屬性名稱活匹配類型,bean屬性可以自動進行裝配。而構造函數可以根據匹配類型自動裝配。你甚至可以設置自動裝配進行自動偵測,這樣Spring替你就會選擇一個合適的機制。請看下面的例子:

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

OrderService類的屬性名被用來和容器中的一個bean實例進行匹配。自動裝配會默默的保存一些類型信息並降低混亂。然而,由於它會犧牲掉這種配置的直觀性和可維護性,你在實際的項目中將不會用到它。許多指南和陳述材料都把它吹捧為Spring的一個非常cool的特性,而沒有提到它的這個缺點。依我之見,就像Spring的對象池一樣,它更多了一些商業味道。它看起來好像可以使XML配置文件更精簡一些,但實際上卻增加其複雜性,尤其是在你的較大規模的工程中已經定義了很多bean的時候更是如此。Spring允許你混合使用自動和手動裝配,但是這種矛盾會使XML配置更加的令人費解。

2. 使用命名規範

和Java編碼的理念一樣,在項目中始終用清晰的,描述性的,一致的命名規範對開發人員理解XML配置非常有用。拿bean ID舉例來說,你可以遵循Java類中屬性的命名規範。比如說,OrderServiceDAO的bean ID應該是orderServiceDAO。對於大項目來說,在bean ID前加包名來作為前綴。

3. 使用簡化格式

簡化格式有利於減少冗餘,因為它把屬性值和引用作為屬性,而不是子元素。看下面的例子:

架構師成長之路-Java程序員必須掌握Spring XML配置的12個技巧

<bean id="orderService"
class="com.lizjason.spring.OrderService">
<property name="companyName">
<value>lizjason</value>
</property>
<constructor-arg>
<ref bean="orderDAO">
</constructor-arg>
</bean>
架構師成長之路-Java程序員必須掌握Spring XML配置的12個技巧

以上程序可以重新以簡化格式書寫為:

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

簡化格式在1.2版本時已經可用了,但請注意不存在<ref local="...">這種簡化格式不僅可以較少你的代碼輸入量,而且可以使XML配置更加的清晰。當你的配置文件中存在大量的bean定義時,它可以顯著地提高可讀性。

4. 儘量使用type而不是index去解決構造函數參數的匹配問題

當構造函數中有多個同類型的參數時,Spring只允許你使用從0開始的index或者value標籤來解決這個問題。請看下面的例子:

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

最好用type屬性取代上面的做法:

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

用index可以稍微減少冗餘,但是它更容易出錯且不如type屬性可讀性高。你應該僅在構造函數中有參數衝突時使用index。

5. 如可能,儘量複用bean定義

Spring提供了一種類似於繼承的機制來降低配置信息的重複並使XML配置更加的簡單。一個子bean可以從它的父bean繼承配置信息,本質上這個父bean就像它的子bean的一個模板。這是一個在大型項目中必須使用的特性。所有你要做的就是把父bean的abstract屬性置為true,並在子bean中加以引用。例如:

架構師成長之路-Java程序員必須掌握Spring XML配置的12個技巧

<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>
架構師成長之路-Java程序員必須掌握Spring XML配置的12個技巧

shippingService bean繼承了abstractService bean的屬性companyName的值lizjason。注意,如果你為bean聲名一個class或工廠方法,這個bean將會默認為abstract

6. 儘量使用ApplicationContext裝配bean,而不是用import

像Ant腳本中imports一樣,Spring的import 元素對於模塊化bean的裝配非常有用,例如:

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

然而,比起在XML中用imports預裝配這些bean,利用ApplicationContext來配置它們將更加靈活,也可以使XML配置更加的易於管理。你可以像下面這樣傳遞一個bean定義數組到ApplicationContext的構造函數中:

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

7. 用id來標識bean

你可以用id或名字作為bean的標識。用id可讀性較差,但是它可以影響XML分析器使bean的reference有效。如果id由於XML IDREF約束而無法使用,你可以用name作為bean的標識。XML IDREF約束是指id必須以字母開始(或者是在XML聲名了的一個標點符號),後面可以是字母,數字,連字符,下劃線,冒號或full stops(不知道怎麼翻譯好)。在實際應用中很少會遇到XML IDREF約束問題。

8. 在開發階段使用依賴檢查

你可以為bean的dependency-check屬性設置一個值來取代默認的none,比如說simple,objects或者all,這樣的話容器將替你做依賴有效性的檢查。當一個bean的所有屬性(或者某些屬性目錄)都被明確設置,或利用自動裝配時將會非常有用。

架構師成長之路-Java程序員必須掌握Spring XML配置的12個技巧

<bean id="orderService"
class="com.lizjason.spring.OrderService"
dependency-check="objects">
<property name="companyName"
value="lizjason"/>
<constructor-arg ref="orderDAO"/>
</bean>
架構師成長之路-Java程序員必須掌握Spring XML配置的12個技巧

在這個例子中,容器將確保這些屬性不是privitives或者保證collections是為orderService bean設置的。為所有的bean設置默認的依賴檢查是可能的,但這個特性由於有些bean的屬性不需要設置而很少使用。

9. 為每個配置文件加一個描述註釋

在XML配置文件中最好使用有描述性的id和name,而不是成堆的註釋。另外,加一個文件描述頭將會非常有用,這個描述可以概括文件中定義的bean。另一個選擇,你可以在description元素中加入描述信息。例如:

架構師成長之路-Java程序員必須掌握Spring XML配置的12個技巧

<beans>
<description>
This file defines billing service
related beans and it depends on
baseServices.xml,which provides
service bean templates...
</description>
...
</beans>
"
架構師成長之路-Java程序員必須掌握Spring XML配置的12個技巧

引言

Spring是一個強有力的Java程序框架,其被廣泛應用於Java的程序中。它用POJO提供了企業級服務。Spring利用依賴注入可以獲得簡單而有效的測試能力。Spring beans,依賴關係,以及服務所需要的bean都將在配置文件中予以描述,配置文件一般採用XML格式。然而XML配置文件冗長而不易使用,在你進行一個使用了大量bean的大項目中它將變得難以閱讀和控制。

在這篇文章中我將給你展示12種的有關Spring XML配置文件的最佳技巧。它們中的一些具有更多的實際意義,而不僅是最好的技巧。請注意另外一些因素,例如域模型的設計,會影響到XML配置,但是這篇文章更關注於XML配置的可讀性和可操控性。

1. 避免使用自動裝配

Spring可以通過bean類的自省來實現自動裝配依賴,這樣的話你就不必明確地描述bean的屬性或者構造函數的參數。根據屬性名稱活匹配類型,bean屬性可以自動進行裝配。而構造函數可以根據匹配類型自動裝配。你甚至可以設置自動裝配進行自動偵測,這樣Spring替你就會選擇一個合適的機制。請看下面的例子:

Spring可以通過bean類的自省來實現自動裝配依賴,這樣的話你就不必明確地描述bean的屬性或者構造函數的參數。根據屬性名稱活匹配類型,bean屬性可以自動進行裝配。而構造函數可以根據匹配類型自動裝配。你甚至可以設置自動裝配進行自動偵測,這樣Spring替你就會選擇一個合適的機制。請看下面的例子:

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

OrderService類的屬性名被用來和容器中的一個bean實例進行匹配。自動裝配會默默的保存一些類型信息並降低混亂。然而,由於它會犧牲掉這種配置的直觀性和可維護性,你在實際的項目中將不會用到它。許多指南和陳述材料都把它吹捧為Spring的一個非常cool的特性,而沒有提到它的這個缺點。依我之見,就像Spring的對象池一樣,它更多了一些商業味道。它看起來好像可以使XML配置文件更精簡一些,但實際上卻增加其複雜性,尤其是在你的較大規模的工程中已經定義了很多bean的時候更是如此。Spring允許你混合使用自動和手動裝配,但是這種矛盾會使XML配置更加的令人費解。

2. 使用命名規範

和Java編碼的理念一樣,在項目中始終用清晰的,描述性的,一致的命名規範對開發人員理解XML配置非常有用。拿bean ID舉例來說,你可以遵循Java類中屬性的命名規範。比如說,OrderServiceDAO的bean ID應該是orderServiceDAO。對於大項目來說,在bean ID前加包名來作為前綴。

3. 使用簡化格式

簡化格式有利於減少冗餘,因為它把屬性值和引用作為屬性,而不是子元素。看下面的例子:

架構師成長之路-Java程序員必須掌握Spring XML配置的12個技巧

<bean id="orderService"
class="com.lizjason.spring.OrderService">
<property name="companyName">
<value>lizjason</value>
</property>
<constructor-arg>
<ref bean="orderDAO">
</constructor-arg>
</bean>
架構師成長之路-Java程序員必須掌握Spring XML配置的12個技巧

以上程序可以重新以簡化格式書寫為:

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

簡化格式在1.2版本時已經可用了,但請注意不存在<ref local="...">這種簡化格式不僅可以較少你的代碼輸入量,而且可以使XML配置更加的清晰。當你的配置文件中存在大量的bean定義時,它可以顯著地提高可讀性。

4. 儘量使用type而不是index去解決構造函數參數的匹配問題

當構造函數中有多個同類型的參數時,Spring只允許你使用從0開始的index或者value標籤來解決這個問題。請看下面的例子:

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

最好用type屬性取代上面的做法:

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

用index可以稍微減少冗餘,但是它更容易出錯且不如type屬性可讀性高。你應該僅在構造函數中有參數衝突時使用index。

5. 如可能,儘量複用bean定義

Spring提供了一種類似於繼承的機制來降低配置信息的重複並使XML配置更加的簡單。一個子bean可以從它的父bean繼承配置信息,本質上這個父bean就像它的子bean的一個模板。這是一個在大型項目中必須使用的特性。所有你要做的就是把父bean的abstract屬性置為true,並在子bean中加以引用。例如:

架構師成長之路-Java程序員必須掌握Spring XML配置的12個技巧

<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>
架構師成長之路-Java程序員必須掌握Spring XML配置的12個技巧

shippingService bean繼承了abstractService bean的屬性companyName的值lizjason。注意,如果你為bean聲名一個class或工廠方法,這個bean將會默認為abstract

6. 儘量使用ApplicationContext裝配bean,而不是用import

像Ant腳本中imports一樣,Spring的import 元素對於模塊化bean的裝配非常有用,例如:

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

然而,比起在XML中用imports預裝配這些bean,利用ApplicationContext來配置它們將更加靈活,也可以使XML配置更加的易於管理。你可以像下面這樣傳遞一個bean定義數組到ApplicationContext的構造函數中:

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

7. 用id來標識bean

你可以用id或名字作為bean的標識。用id可讀性較差,但是它可以影響XML分析器使bean的reference有效。如果id由於XML IDREF約束而無法使用,你可以用name作為bean的標識。XML IDREF約束是指id必須以字母開始(或者是在XML聲名了的一個標點符號),後面可以是字母,數字,連字符,下劃線,冒號或full stops(不知道怎麼翻譯好)。在實際應用中很少會遇到XML IDREF約束問題。

8. 在開發階段使用依賴檢查

你可以為bean的dependency-check屬性設置一個值來取代默認的none,比如說simple,objects或者all,這樣的話容器將替你做依賴有效性的檢查。當一個bean的所有屬性(或者某些屬性目錄)都被明確設置,或利用自動裝配時將會非常有用。

架構師成長之路-Java程序員必須掌握Spring XML配置的12個技巧

<bean id="orderService"
class="com.lizjason.spring.OrderService"
dependency-check="objects">
<property name="companyName"
value="lizjason"/>
<constructor-arg ref="orderDAO"/>
</bean>
架構師成長之路-Java程序員必須掌握Spring XML配置的12個技巧

在這個例子中,容器將確保這些屬性不是privitives或者保證collections是為orderService bean設置的。為所有的bean設置默認的依賴檢查是可能的,但這個特性由於有些bean的屬性不需要設置而很少使用。

9. 為每個配置文件加一個描述註釋

在XML配置文件中最好使用有描述性的id和name,而不是成堆的註釋。另外,加一個文件描述頭將會非常有用,這個描述可以概括文件中定義的bean。另一個選擇,你可以在description元素中加入描述信息。例如:

架構師成長之路-Java程序員必須掌握Spring XML配置的12個技巧

<beans>
<description>
This file defines billing service
related beans and it depends on
baseServices.xml,which provides
service bean templates...
</description>
...
</beans>
架構師成長之路-Java程序員必須掌握Spring XML配置的12個技巧

用description元素的一個好處就是工具可以很容易的把描述信息從這個元素中提取出來。

10. 和team members溝通變更

當你修改java源碼後,要確保更改了配置文件中的相應部分並把這個情況告知你的team members。XML配置文件也是代碼,它們是程序的重要組成部分,但它們很難閱讀和維護。大多數時間裡,你需要同時看XML配置文件和java代碼才能知道是怎麼回事。

11. setter注入和構造函數注入,優先使用前者

Spring提供了三種注入方式:構造函數注入,setter注入和方法注入。一般我們使用前兩種。

"
架構師成長之路-Java程序員必須掌握Spring XML配置的12個技巧

引言

Spring是一個強有力的Java程序框架,其被廣泛應用於Java的程序中。它用POJO提供了企業級服務。Spring利用依賴注入可以獲得簡單而有效的測試能力。Spring beans,依賴關係,以及服務所需要的bean都將在配置文件中予以描述,配置文件一般採用XML格式。然而XML配置文件冗長而不易使用,在你進行一個使用了大量bean的大項目中它將變得難以閱讀和控制。

在這篇文章中我將給你展示12種的有關Spring XML配置文件的最佳技巧。它們中的一些具有更多的實際意義,而不僅是最好的技巧。請注意另外一些因素,例如域模型的設計,會影響到XML配置,但是這篇文章更關注於XML配置的可讀性和可操控性。

1. 避免使用自動裝配

Spring可以通過bean類的自省來實現自動裝配依賴,這樣的話你就不必明確地描述bean的屬性或者構造函數的參數。根據屬性名稱活匹配類型,bean屬性可以自動進行裝配。而構造函數可以根據匹配類型自動裝配。你甚至可以設置自動裝配進行自動偵測,這樣Spring替你就會選擇一個合適的機制。請看下面的例子:

Spring可以通過bean類的自省來實現自動裝配依賴,這樣的話你就不必明確地描述bean的屬性或者構造函數的參數。根據屬性名稱活匹配類型,bean屬性可以自動進行裝配。而構造函數可以根據匹配類型自動裝配。你甚至可以設置自動裝配進行自動偵測,這樣Spring替你就會選擇一個合適的機制。請看下面的例子:

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

OrderService類的屬性名被用來和容器中的一個bean實例進行匹配。自動裝配會默默的保存一些類型信息並降低混亂。然而,由於它會犧牲掉這種配置的直觀性和可維護性,你在實際的項目中將不會用到它。許多指南和陳述材料都把它吹捧為Spring的一個非常cool的特性,而沒有提到它的這個缺點。依我之見,就像Spring的對象池一樣,它更多了一些商業味道。它看起來好像可以使XML配置文件更精簡一些,但實際上卻增加其複雜性,尤其是在你的較大規模的工程中已經定義了很多bean的時候更是如此。Spring允許你混合使用自動和手動裝配,但是這種矛盾會使XML配置更加的令人費解。

2. 使用命名規範

和Java編碼的理念一樣,在項目中始終用清晰的,描述性的,一致的命名規範對開發人員理解XML配置非常有用。拿bean ID舉例來說,你可以遵循Java類中屬性的命名規範。比如說,OrderServiceDAO的bean ID應該是orderServiceDAO。對於大項目來說,在bean ID前加包名來作為前綴。

3. 使用簡化格式

簡化格式有利於減少冗餘,因為它把屬性值和引用作為屬性,而不是子元素。看下面的例子:

架構師成長之路-Java程序員必須掌握Spring XML配置的12個技巧

<bean id="orderService"
class="com.lizjason.spring.OrderService">
<property name="companyName">
<value>lizjason</value>
</property>
<constructor-arg>
<ref bean="orderDAO">
</constructor-arg>
</bean>
架構師成長之路-Java程序員必須掌握Spring XML配置的12個技巧

以上程序可以重新以簡化格式書寫為:

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

簡化格式在1.2版本時已經可用了,但請注意不存在<ref local="...">這種簡化格式不僅可以較少你的代碼輸入量,而且可以使XML配置更加的清晰。當你的配置文件中存在大量的bean定義時,它可以顯著地提高可讀性。

4. 儘量使用type而不是index去解決構造函數參數的匹配問題

當構造函數中有多個同類型的參數時,Spring只允許你使用從0開始的index或者value標籤來解決這個問題。請看下面的例子:

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

最好用type屬性取代上面的做法:

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

用index可以稍微減少冗餘,但是它更容易出錯且不如type屬性可讀性高。你應該僅在構造函數中有參數衝突時使用index。

5. 如可能,儘量複用bean定義

Spring提供了一種類似於繼承的機制來降低配置信息的重複並使XML配置更加的簡單。一個子bean可以從它的父bean繼承配置信息,本質上這個父bean就像它的子bean的一個模板。這是一個在大型項目中必須使用的特性。所有你要做的就是把父bean的abstract屬性置為true,並在子bean中加以引用。例如:

架構師成長之路-Java程序員必須掌握Spring XML配置的12個技巧

<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>
架構師成長之路-Java程序員必須掌握Spring XML配置的12個技巧

shippingService bean繼承了abstractService bean的屬性companyName的值lizjason。注意,如果你為bean聲名一個class或工廠方法,這個bean將會默認為abstract

6. 儘量使用ApplicationContext裝配bean,而不是用import

像Ant腳本中imports一樣,Spring的import 元素對於模塊化bean的裝配非常有用,例如:

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

然而,比起在XML中用imports預裝配這些bean,利用ApplicationContext來配置它們將更加靈活,也可以使XML配置更加的易於管理。你可以像下面這樣傳遞一個bean定義數組到ApplicationContext的構造函數中:

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

7. 用id來標識bean

你可以用id或名字作為bean的標識。用id可讀性較差,但是它可以影響XML分析器使bean的reference有效。如果id由於XML IDREF約束而無法使用,你可以用name作為bean的標識。XML IDREF約束是指id必須以字母開始(或者是在XML聲名了的一個標點符號),後面可以是字母,數字,連字符,下劃線,冒號或full stops(不知道怎麼翻譯好)。在實際應用中很少會遇到XML IDREF約束問題。

8. 在開發階段使用依賴檢查

你可以為bean的dependency-check屬性設置一個值來取代默認的none,比如說simple,objects或者all,這樣的話容器將替你做依賴有效性的檢查。當一個bean的所有屬性(或者某些屬性目錄)都被明確設置,或利用自動裝配時將會非常有用。

架構師成長之路-Java程序員必須掌握Spring XML配置的12個技巧

<bean id="orderService"
class="com.lizjason.spring.OrderService"
dependency-check="objects">
<property name="companyName"
value="lizjason"/>
<constructor-arg ref="orderDAO"/>
</bean>
架構師成長之路-Java程序員必須掌握Spring XML配置的12個技巧

在這個例子中,容器將確保這些屬性不是privitives或者保證collections是為orderService bean設置的。為所有的bean設置默認的依賴檢查是可能的,但這個特性由於有些bean的屬性不需要設置而很少使用。

9. 為每個配置文件加一個描述註釋

在XML配置文件中最好使用有描述性的id和name,而不是成堆的註釋。另外,加一個文件描述頭將會非常有用,這個描述可以概括文件中定義的bean。另一個選擇,你可以在description元素中加入描述信息。例如:

架構師成長之路-Java程序員必須掌握Spring XML配置的12個技巧

<beans>
<description>
This file defines billing service
related beans and it depends on
baseServices.xml,which provides
service bean templates...
</description>
...
</beans>
架構師成長之路-Java程序員必須掌握Spring XML配置的12個技巧

用description元素的一個好處就是工具可以很容易的把描述信息從這個元素中提取出來。

10. 和team members溝通變更

當你修改java源碼後,要確保更改了配置文件中的相應部分並把這個情況告知你的team members。XML配置文件也是代碼,它們是程序的重要組成部分,但它們很難閱讀和維護。大多數時間裡,你需要同時看XML配置文件和java代碼才能知道是怎麼回事。

11. setter注入和構造函數注入,優先使用前者

Spring提供了三種注入方式:構造函數注入,setter注入和方法注入。一般我們使用前兩種。

架構師成長之路-Java程序員必須掌握Spring XML配置的12個技巧

<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>
"
架構師成長之路-Java程序員必須掌握Spring XML配置的12個技巧

引言

Spring是一個強有力的Java程序框架,其被廣泛應用於Java的程序中。它用POJO提供了企業級服務。Spring利用依賴注入可以獲得簡單而有效的測試能力。Spring beans,依賴關係,以及服務所需要的bean都將在配置文件中予以描述,配置文件一般採用XML格式。然而XML配置文件冗長而不易使用,在你進行一個使用了大量bean的大項目中它將變得難以閱讀和控制。

在這篇文章中我將給你展示12種的有關Spring XML配置文件的最佳技巧。它們中的一些具有更多的實際意義,而不僅是最好的技巧。請注意另外一些因素,例如域模型的設計,會影響到XML配置,但是這篇文章更關注於XML配置的可讀性和可操控性。

1. 避免使用自動裝配

Spring可以通過bean類的自省來實現自動裝配依賴,這樣的話你就不必明確地描述bean的屬性或者構造函數的參數。根據屬性名稱活匹配類型,bean屬性可以自動進行裝配。而構造函數可以根據匹配類型自動裝配。你甚至可以設置自動裝配進行自動偵測,這樣Spring替你就會選擇一個合適的機制。請看下面的例子:

Spring可以通過bean類的自省來實現自動裝配依賴,這樣的話你就不必明確地描述bean的屬性或者構造函數的參數。根據屬性名稱活匹配類型,bean屬性可以自動進行裝配。而構造函數可以根據匹配類型自動裝配。你甚至可以設置自動裝配進行自動偵測,這樣Spring替你就會選擇一個合適的機制。請看下面的例子:

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

OrderService類的屬性名被用來和容器中的一個bean實例進行匹配。自動裝配會默默的保存一些類型信息並降低混亂。然而,由於它會犧牲掉這種配置的直觀性和可維護性,你在實際的項目中將不會用到它。許多指南和陳述材料都把它吹捧為Spring的一個非常cool的特性,而沒有提到它的這個缺點。依我之見,就像Spring的對象池一樣,它更多了一些商業味道。它看起來好像可以使XML配置文件更精簡一些,但實際上卻增加其複雜性,尤其是在你的較大規模的工程中已經定義了很多bean的時候更是如此。Spring允許你混合使用自動和手動裝配,但是這種矛盾會使XML配置更加的令人費解。

2. 使用命名規範

和Java編碼的理念一樣,在項目中始終用清晰的,描述性的,一致的命名規範對開發人員理解XML配置非常有用。拿bean ID舉例來說,你可以遵循Java類中屬性的命名規範。比如說,OrderServiceDAO的bean ID應該是orderServiceDAO。對於大項目來說,在bean ID前加包名來作為前綴。

3. 使用簡化格式

簡化格式有利於減少冗餘,因為它把屬性值和引用作為屬性,而不是子元素。看下面的例子:

架構師成長之路-Java程序員必須掌握Spring XML配置的12個技巧

<bean id="orderService"
class="com.lizjason.spring.OrderService">
<property name="companyName">
<value>lizjason</value>
</property>
<constructor-arg>
<ref bean="orderDAO">
</constructor-arg>
</bean>
架構師成長之路-Java程序員必須掌握Spring XML配置的12個技巧

以上程序可以重新以簡化格式書寫為:

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

簡化格式在1.2版本時已經可用了,但請注意不存在<ref local="...">這種簡化格式不僅可以較少你的代碼輸入量,而且可以使XML配置更加的清晰。當你的配置文件中存在大量的bean定義時,它可以顯著地提高可讀性。

4. 儘量使用type而不是index去解決構造函數參數的匹配問題

當構造函數中有多個同類型的參數時,Spring只允許你使用從0開始的index或者value標籤來解決這個問題。請看下面的例子:

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

最好用type屬性取代上面的做法:

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

用index可以稍微減少冗餘,但是它更容易出錯且不如type屬性可讀性高。你應該僅在構造函數中有參數衝突時使用index。

5. 如可能,儘量複用bean定義

Spring提供了一種類似於繼承的機制來降低配置信息的重複並使XML配置更加的簡單。一個子bean可以從它的父bean繼承配置信息,本質上這個父bean就像它的子bean的一個模板。這是一個在大型項目中必須使用的特性。所有你要做的就是把父bean的abstract屬性置為true,並在子bean中加以引用。例如:

架構師成長之路-Java程序員必須掌握Spring XML配置的12個技巧

<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>
架構師成長之路-Java程序員必須掌握Spring XML配置的12個技巧

shippingService bean繼承了abstractService bean的屬性companyName的值lizjason。注意,如果你為bean聲名一個class或工廠方法,這個bean將會默認為abstract

6. 儘量使用ApplicationContext裝配bean,而不是用import

像Ant腳本中imports一樣,Spring的import 元素對於模塊化bean的裝配非常有用,例如:

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

然而,比起在XML中用imports預裝配這些bean,利用ApplicationContext來配置它們將更加靈活,也可以使XML配置更加的易於管理。你可以像下面這樣傳遞一個bean定義數組到ApplicationContext的構造函數中:

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

7. 用id來標識bean

你可以用id或名字作為bean的標識。用id可讀性較差,但是它可以影響XML分析器使bean的reference有效。如果id由於XML IDREF約束而無法使用,你可以用name作為bean的標識。XML IDREF約束是指id必須以字母開始(或者是在XML聲名了的一個標點符號),後面可以是字母,數字,連字符,下劃線,冒號或full stops(不知道怎麼翻譯好)。在實際應用中很少會遇到XML IDREF約束問題。

8. 在開發階段使用依賴檢查

你可以為bean的dependency-check屬性設置一個值來取代默認的none,比如說simple,objects或者all,這樣的話容器將替你做依賴有效性的檢查。當一個bean的所有屬性(或者某些屬性目錄)都被明確設置,或利用自動裝配時將會非常有用。

架構師成長之路-Java程序員必須掌握Spring XML配置的12個技巧

<bean id="orderService"
class="com.lizjason.spring.OrderService"
dependency-check="objects">
<property name="companyName"
value="lizjason"/>
<constructor-arg ref="orderDAO"/>
</bean>
架構師成長之路-Java程序員必須掌握Spring XML配置的12個技巧

在這個例子中,容器將確保這些屬性不是privitives或者保證collections是為orderService bean設置的。為所有的bean設置默認的依賴檢查是可能的,但這個特性由於有些bean的屬性不需要設置而很少使用。

9. 為每個配置文件加一個描述註釋

在XML配置文件中最好使用有描述性的id和name,而不是成堆的註釋。另外,加一個文件描述頭將會非常有用,這個描述可以概括文件中定義的bean。另一個選擇,你可以在description元素中加入描述信息。例如:

架構師成長之路-Java程序員必須掌握Spring XML配置的12個技巧

<beans>
<description>
This file defines billing service
related beans and it depends on
baseServices.xml,which provides
service bean templates...
</description>
...
</beans>
架構師成長之路-Java程序員必須掌握Spring XML配置的12個技巧

用description元素的一個好處就是工具可以很容易的把描述信息從這個元素中提取出來。

10. 和team members溝通變更

當你修改java源碼後,要確保更改了配置文件中的相應部分並把這個情況告知你的team members。XML配置文件也是代碼,它們是程序的重要組成部分,但它們很難閱讀和維護。大多數時間裡,你需要同時看XML配置文件和java代碼才能知道是怎麼回事。

11. setter注入和構造函數注入,優先使用前者

Spring提供了三種注入方式:構造函數注入,setter注入和方法注入。一般我們使用前兩種。

架構師成長之路-Java程序員必須掌握Spring XML配置的12個技巧

<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>
架構師成長之路-Java程序員必須掌握Spring XML配置的12個技巧

在這個例子中,orderService bean用了構造函數注入,而BillingService bean用了setter注入。構造函數注入可以確保bean正確地構建,但是setter注入更加的靈活和易於控制,特別是當class有多個屬性並且它們中的一些是可選的情況是更是如此。

12. 不要濫用注入

就像前面提到的,Spring的ApplicationContext可以替你創建java對象,但不是所有的java對象都應該通過注入創建。例如,域對象就不應該通過ApplicationContext創建。Spring是一個優秀的框架,但是考慮到可讀性和可操控性,基於XML配置的配置會在定義很多bean的時候出現麻煩。過渡使用依賴注入將會使XML配置更加的複雜和冗長。切記,當使用高效的IDE時,例如Eclipse and IntelliJ,java代碼更加的易於閱讀,維護和管理比使XML文件

小結

想了解學習Java方面的技術以及學習進階哪方面的技術知識點等

私信本頭條號:發送:“免費資料”就可以獲取Java架構學習資料

微服務、分佈式、高併發、高可用,性能優化丶源碼分析等等一些技術

歡迎關注頭條號:JAVA大飛哥

覺得收穫的話可以點個關注收藏轉發一波喔,謝謝大佬們支持!

最後,每一位讀到這裡的Java程序猿朋友們,感謝你們能耐心地看完。希望在成為一名更優秀的Java程序猿的道路上,我們可以一起學習、一起進步!都能贏取白富美,走向架構師的人生巔峰!

"

相關推薦

推薦中...