Spring如今有了強大的自動化配置和基於Java的配置,XML不該該再是你的第一選擇了。不過,鑑於已經存在那麼多基於XML的Spring配置,因此理解如何在Spring中使用XML仍是很重要的。可是,我但願本節的內容只是用來幫助你維護已有的XML配置,在完成新的Spring工做時,但願你會使用自動化配置和JavaConfig。java
在使用XML爲Spring裝配bean以前,你須要建立一個新的配置規範。在使用JavaConfig的時候,這意味着要建立一個帶有@Configuration註解的類,而在XML配置中,這意味着要建立一個XML文件,而且要以<beans>元素爲根。spring
最爲簡單的Spring XML配置以下所示:數組
很容易就能看出來,這個基本的XML配置已經比同等功能的JavaConfig類複雜得多了。做爲起步,在JavaConfig中所須要的只是@Configuration,但在使用XML時,須要在配置文件的頂部聲明多個XML模式(XSD)文件來約束格式,這些文件定義了配置Spring的XML元素。函數
要在基於XML的Spring配置中聲明一個bean,咱們要使用spring-beans模式中的另一個元素:<bean>。<bean>元素相似於JavaConfig中的@Bean註解。測試
咱們能夠按照以下的方式聲明CompactDiscbean:spa
這裏聲明瞭一個很簡單的bean,建立這個bean的類經過class屬性來指定的,它將會調用SgtPeppers的默認構造器來建立bean,而且要使用全限定的類名。藉助id屬性,爲每一個bean設置一個名字(在裝配到其餘bean的時須要根據準確的名字)。
補充:限定類名,就是類名全稱,帶包路徑的用點隔開,例如: java.lang.String。非限定(non-qualified)類名也叫短名,就是咱們平時說的類名,不帶包的,例如:String。3d
在Spring XML配置中,只有一種聲明bean的方式:使用<bean>元素並指定class屬性。Spring會從這裏獲取必要的信息來建立bean。可是,在XML中聲明DI時,會有多種可選的配置方案和風格。具體到構造器注入,有兩種基本的配置方案可供選擇:對象
接下來,看一下它們各自如何注入bean引用。blog
例子場景:建立一個CDPlayer(CD播放器)的bean,須要有一個接收CompactDisc(CD盤)類型的構造器。it
當Spring遇到這個<bean>元素時,它會建立一個CDPlayer實例。<constructor-arg>元素會告知Spring要將一個ID爲compactDisc的bean引用傳遞到CDPlayer的構造器中。
做爲替代的方案,你也可使用Spring的c-命名空間。c-命名空間是在Spring 3.0中引入的,它是在XML中更爲簡潔地描述構造器參數的方式。要使用它的話,必需要在XML的頂部聲明其模式,以下所示:
在c-命名空間和模式聲明以後,咱們就可使用它來聲明構造器參數了,以下所示:
配置結構圖:(這裏粗略的講解c-命名空間)
補充:字面量就是值 不聲明變量儲存。例如 int a = 0; a = a + 3; a 是變量 3是字面量;
CompactDisc的一個新實現,有參構造函數的參數是基本類型(直接傳字面量)而不是對象的引用時:
XML的配置:
c-命名空間:
在裝配bean引用和字面量值方面,<constructor-arg>和c-命名空間的功能是相同的。可是有一種狀況是<constructor-arg>可以實現,c-命名空間卻沒法作到的。接下來,讓咱們看一下如何將集合裝配到構造器參數中。
需求:若是使用CompactDisc爲真正的CD建模,那麼它也應該有磁道列表(tracks)的概念,每一個磁道上包含一首歌。請考慮下面這個新的BlankDisc:
在聲明bean的時候,咱們必需要提供一個磁道列表。要達到這一點,咱們能夠有多個可選方案。首先,可使用<list>元素將其聲明爲一個列表:
其中,<list>元素是<constructor-arg>的子元素,這代表一個包含值的列表將會傳遞到構造器中。其中,<value>元素用來指定列表中的每一個元素。
與之相似,咱們也可使用<ref>元素替代<value>,實現bean引用列表的裝配。例如,假設你有一個Discography類,它的構造器以下所示(集合泛型爲對象引用):
那麼,你能夠採起以下的方式配置Discography bean:
當構造器參數的類型是java.util.List時,使用<list>元素是合情合理的。儘管如此,咱們也能夠按照一樣的方式使用<set>元素:
<set>和<list>元素的區別不大,其中最重要的不一樣在於當Spring建立要裝配的集合時,所建立的是java.util.Set仍是java.util.List。若是是Set的話,全部重複的值都會被忽略掉,存放順序也不會得以保證。不過不管在哪一種狀況下,<set>或<list>均可以用來裝配List、Set甚至數組。
到目前爲止,CDPlayer和BlankDisc類徹底是經過構造器注入的,沒有使用屬性的Setter方法。接下來,咱們就看一下如何使用Spring XML實現屬性注入。假設屬性注入的CDPlayer以下所示:
該選擇構造器注入仍是屬性注入呢?做爲一個通用的規則,我傾向於對強依賴使用構造器注入,而對可選性的依賴使用屬性注入。如今,CDPlayer沒有任何的構造器(除了隱含的默認構造器),它也沒有任何的強依賴。所以,你能夠採用以下的方式將其聲明爲
Spring bean:
Spring在建立bean的時候不會有任何的問題,可是CDPlayerTest會由於出現NullPointerException而致使測試失敗,由於咱們並無注入CDPlayer的compactDisc屬性。不過,按照以下的方式修改XML,就能解決該問題
<property>元素爲屬性的Setter方法所提供的功能與<constructor-arg>元素爲構造器所提供的功能是同樣的。在本例中,它引用了ID爲compactDisc的bean(經過ref屬性),並將其注入到compactDisc屬性中(經過setCompactDisc()方法)
Spring爲<constructor-arg>元素提供了c-命名空間做爲替代方案,與之相似,Spring提供了更加簡潔的p-命名空間,做爲<property>元素的替代方案。爲了啓用p-命名空間,必需要在XML文件中與其餘的命名空間一塊兒對其進行聲明:
咱們可使用p-命名空間,按照如下的方式裝配compactDisc屬性:
p-命名空間中屬性所遵循的命名約定與c-命名空間中的屬性相似。
屬性也能夠注入字面量,這與構造器參數很是相似。做爲示例,咱們從新看一下BlankDisc bean,新的BlankDisc類以下所示:
咱們須要裝配這些屬性,能夠藉助<property>元素的value屬性實現該功能:
在這裏,除了使用<property>元素的value屬性來設置title和artist,咱們還使用了內嵌的<list>元素來設置tracks屬性;另一種可選方案就是使用p-命名空間的屬性來完成該功能:
與c-命名空間同樣,裝配bean引用與裝配字面量的惟一區別在因而否帶有「-ref」後綴。若是沒有「-ref」後綴的話,所裝配的就是字面量。
咱們不能使用p-命名空間來裝配集合,沒有便利的方式使用p-命名空間來指定一個值(或bean引用)的列表。可是,咱們可使用Spring util-命名空間中的一些功能來簡化BlankDiscbean。(不作詳細說明)