關于Bean是如何配置的,大家并不陌生,畢竟前文曾有涉及,雖然比較粗淺,卻也介紹了如何寫份XML組態檔,告訴Spring容器怎樣創建Bean,怎樣注入依賴,等等,其中要點如下:
1.<bean>元素用于配置Bean;具有id,class兩個重要XML屬性:id用于指定Bean的唯一識別符號;class用于指定Bean的型別,其值為全限定類名,
2.<property>元素用于配置通過屬性注入依賴;具有name,value,ref三個重要XML屬性:name用于指定Bean的屬性名;value用于指定注入的字面量值;ref用于指定注入的Bean參考,
因此,假如com.dream包現有這樣一些類:
1 public class Music { 2 private String musicName = null; 3 4 public String getMusicName() { 5 return this.musicName; 6 } 7 8 public void setMusicName(String musicName) { 9 this.musicName = musicName; 10 } 11 }
1 public class Player { 2 private Music playingMusic = null; 3 4 public Music getPlayingMusic() { 5 return this.playingMusic; 6 } 7 8 public void setPlayingMusic(Music playingMusic) { 9 this.playingMusic = playingMusic; 10 } 11 }
則可這樣配置Bean:
1 <beans /* 省略命名空間和XSD模式檔案宣告 */> 2 <bean id="music" class="com.dream.Music"> 3 <property name="musicName" value="執著"/> 4 </bean> 5 <bean id="player" class="com.dream.Player"> 6 <property name="playingMusic" ref="music"/> 7 </bean> 8 </beans>
這段配置能夠告訴Spring容器創建music,player這兩個Bean之后,通過屬性注入Bean所需的依賴,也就是通過<property>元素,把“執著”注入music的musicName屬性,把music注入player的playingMusic屬性,這些配置大家都很熟悉,無需多敘,可是我們尚不知道的是,我們還能使用p-命名空間代替<property>元素描述依賴的注入,而這,需要修改XML組態檔如下:
1 <beans xmlns:p="http://www.springframework.org/schema/p" 2 /* 省略命名空間和XSD模式檔案宣告 */> 3 <bean id="music" class="com.dream.Music" p:musicName="執著"/> 4 <bean id="player" class="com.dream.Player" p:playingMusic-ref="music"/> 5 </beans>
新的配置引入p-命名空間 xmlns:p="http://www.springframework.org/schema/p" 之后,做了兩處改動:
1.使用 p:musicName="執著" 代替<property>元素注入“執著”這個字面量值,
2.使用 p:playingMusic-ref="music" 代替<property>元素注入music這個Bean參考,
這是怎么回事呢?
原來,p-命名空間可以代替<property>元素,以XML屬性這種簡潔緊湊的方式描述通過屬性注入依賴,因此,字面量值注入能用p-命名空間這樣描述: p:Bean的屬性名=“字面量值” ,也就是以 p: 作為開頭,隨后帶上Bean的屬性名,帶上等號,帶上字面量值就行;Bean參考注入能用p-命名空間這樣描述: p:Bean的屬性名-ref=“即將注入的Bean的ID” ,也就是以 p: 作為開頭,隨后帶上Bean的屬性名,帶上 -ref 后綴,帶上等號,帶上即將注入的Bean的ID即可,
因此,修改之后的配置使用p-命名空間 p:musicName="執著" 代替 <property name="musicName" value="https://www.cnblogs.com/evanlin/archive/2022/01/31/執著"/> 描述“執著”這個字面量值的注入;使用p-命名空間 p:playingMusic-ref="music" 代替 <property name="playingMusic" ref="music"/> 描述music這個Bean參考的注入,
于是我們知道了,p-命名空間能以一種簡潔緊湊的方式代替<property>元素描述依賴的注入,至于p-命名空間和<property>元素哪種較好,并無定論,可依個人偏好而定,可是一旦選好了,最好保持整個專案的統一;不要這里使用<property>元素,那里使用p-命名空間,
建構式注入
很多時候,我們希望一步到位,通過建構式完成Bean的創建與裝配,為了滿足這樣的需求,Spring提供了些支持,讓我們能向XML組態檔提供一些資訊,告訴Spring容器創建Bean的時候不是呼叫默認建構式,而是呼叫其它具有某些引數的建構式;從而能在創建Bean的同時通過建構式注入Bean所需的依賴,完成Bean的創建與裝配,
因此,假如com.dream包現有這樣一些類:
1 public class Music { 2 private String musicName = null; 3 4 public Music(String musicName) { 5 this.musicName = musicName; 6 } 7 }
1 public class Player { 2 private Music playingMusic = null; 3 4 public Player(Music playingMusic) { 5 this.playingMusic = playingMusic; 6 } 7 }
則可這樣配置Bean:
1 <beans /* 省略命名空間和XSD模式檔案宣告 */> 2 <bean id="music" class="com.dream.Music"> 3 <constructor-arg type="java.lang.String" value="執著"/> 4 </bean> 5 <bean id="player" class="com.dream.Player"> 6 <constructor-arg type="com.dream.Music" ref="music"/> 7 </bean> 8 </beans>
可以看到建構式注入是用<constructor-arg>元素配置的;具有type,value,ref三個重要XML屬性,type用于指定建構式的引數型別,其值為全限定類名;value用于指定注入的字面量值;ref用于指定注入的Bean參考,Spring容器呼叫類的建構式創建Bean之前會先查看XML配置資訊,看看即將呼叫的建構式具有多少引數,每個引數是什么型別的,值是多少;之后,Spring容器根據組態檔提供的資訊呼叫符合條件的建構式完成Bean的創建與裝配,
就該示例而言,Spring容器讀取配置資訊之后,發現music這個Bean的創建需要呼叫的建構式具有一個String型別的引數,于是,Spring容器根據組態檔提供的資訊把字串“執著”傳給符合條件的建構式,并在呼叫之后完成Bean的創建與裝配;發現player這個Bean的創建需要呼叫的建構式具有一個Music型別的引數,于是,Spring容器根據組態檔提供的資訊把music這個Bean傳給符合條件的建構式,并在呼叫之后完成Bean的創建與裝配,
講到這里,興許大家開始困惑了:“如果配置的建構式具有多個相同型別的引數,Spring容器呼叫建構式的時候,怎么知道該把哪個值傳給哪個引數,完成Bean的創建與裝配呢?”
關于這個問題,我們可以引入<constructor-arg>元素的index屬性進行解決,index屬性能夠指定建構式的引數索引,表明配置的是建構式的第幾個引數,其中,第一個引數的值是0,第二個引數的值是1,第三個引數的值是2,以此類推,Spring容器創建Bean的時候,會按引數索引的順序依次把相應的引數值傳給建構式進行Bean的創建,自然而然的,關于因為相同型別的引數多于一個而無法正確注入依賴的問題也就迎刃而解了,
另外,除了引數索引,我們也能使用<constructor-arg>元素的name屬性解決這個問題,name屬性用于指定建構式的引數名,表明引數值應該傳給引數名為某值的引數,而建構式的引數名一定是各不相同的,因此能夠解決這個問題,只是name屬性的使用有個限制,需要我們打開除錯標記(Debug Flag)編譯代碼才行,否則,Spring容器無法得知建構式的引數名,也就無法通過引數名傳遞引數值呼叫建構式了,
還有,同p-命名空間能夠代替<property>元素一樣,Spring也提供了c-命名空間用于代替<constructor-arg>元素,而這,可以修改XML組態檔如下:
1 <beans xmlns:c="http://www.springframework.org/schema/c" 2 /* 省略命名空間和XSD模式檔案宣告 */> 3 <bean id="music" class="com.dream.Music" c:musicName="執著"/> 4 <bean id="player" class="com.dream.Player" c:playingMusic-ref="music"/> 5 </beans>
新的配置引入c-命名空間 xmlns:c="http://www.springframework.org/schema/c" 之后,做了兩處改動:
1.使用 c:musicName="執著" 代替<constructor-arg>元素注入“執著”這個字面量值,
2.使用 c:playingMusic-ref="music" 代替<constructor-arg>元素注入music這個Bean參考,
這是怎么回事呢?
原來,c-命名空間可以代替<constructor-arg>元素,以XML屬性這種簡潔緊湊的方式描述通過建構式注入依賴,因此,字面量值注入能用c-命名空間這樣描述: c:建構式的引數名=“字面量值” ,也就是以 c: 作為開頭,隨后帶上建構式的引數名,帶上等號,帶上字面量值就行;Bean參考注入能用c-命名空間這樣描述: c:建構式的引數名-ref=“即將注入的Bean的ID” ,也就是以 c: 作為開頭,隨后帶上建構式的引數名,帶上 -ref 后綴,帶上等號,帶上即將注入的Bean的ID即可,
因此,修改之后的配置使用c-命名空間 c:musicName="執著" 代替 <constructor-arg type="java.lang.String" value="https://www.cnblogs.com/evanlin/archive/2022/01/31/執著"/> 描述“執著”這個字面量值的注入;使用c-命名空間 c:playingMusic-ref="music" 代替 <constructor-arg type="com.dream.Music" ref="music"/> 描述music這個Bean參考的注入,
讀到這里,興許大家已經察覺:“c-命名空間用到了引數名,而Spring容器獲取引數名需要除錯標志,如果編譯代碼的時候沒有啟用除錯標志,這種配置方式豈不是有問題?”
是的,確實如此,因此,c-命名空間也支持引數索引,如下所示:
1 <beans xmlns:c="http://www.springframework.org/schema/c" 2 /* 省略命名空間和XSD模式檔案宣告 */> 3 <bean id="music" class="com.dream.Music" c:_0="執著"/> 4 <bean id="player" class="com.dream.Player" c:_0-ref="music"/> 5 </beans>
引入引數索引之后,原來的 c:musicName="執著" 變成 c:_0="執著" ,原來的 c:playingMusic-ref="music" 變成 c:_0-ref="music" ,也就是說,原來的引數名變成下劃線+索引,其中,索引前面的下劃線是必須的,因為XML不允許屬性名以數字作為開頭,引入引數索引之后,Spring容器創建Bean的時候,會按引數索引指定的順序依次把相應的引數值傳給建構式,并在呼叫之后完成Bean的創建與裝配,
于是我們知道了,Spring容器既能通過屬性注入依賴,也能通過建構式注入依賴,至于該用屬性注入還是構建函式注入,則是個人偏好問題,一般而言,強依賴(也就是只有完成注入,程式才能正常運行的依賴)通常選用建構式注入,可選依賴(也就是不管注入有沒有完成,程式都能正常運行的依賴)通常選用屬性注入,
靜態工廠方法注入
總有那么一些時候,我們的類存在一些專門用于創建物件的靜態方法,俗稱靜態工廠方法,如果我們希望通過靜態工廠方法創建Bean,只需向組態檔提供一些資訊,告訴Spring容器呼叫靜態工廠方法完成Bean的創建與裝配即可,
因此,假如com.dream包現有這樣一些類:
1 public class Music { 2 private String musicName = null; 3 4 public Music(String musicName) { 5 this.musicName = musicName; 6 } 7 8 public static Music staticFactory(String musicName) { 9 return new Music(musicName); 10 } 11 }
1 public class Player { 2 private Music playingMusic = null; 3 4 public Player(Music playingMusic) { 5 this.playingMusic = playingMusic; 6 } 7 8 public static Player staticFactory(Music playingMusic) { 9 return new Player(playingMusic); 10 } 11 }
則可這樣配置Bean:
1 <beans /* 省略命名空間和XSD模式檔案宣告 */> 2 <bean id="music" class="com.dream.Music" factory-method="staticFactory"> 3 <constructor-arg type="java.lang.String" value="執著"/> 4 </bean> 5 <bean id="player" class="com.dream.Player" factory-method="staticFactory"> 6 <constructor-arg type="com.dream.Music" ref="music"/> 7 </bean> 8 </beans>
可以看到<bean>元素新添了個factory-method屬性,用于指定類的靜態工廠方法;而靜態工廠方法所屬的類由class屬性指定,所需的引數由<constructor-arg>元素指定,當然,如果靜態工廠方法創建的Bean存在屬性,也可通過<property>元素指定依賴注入,
因此,這段配置用于告訴Spring容器:music這個Bean需要呼叫com.dream.Music類的staticFactory靜態工廠方法進行創建,而且呼叫的時候需要注入“執著”這個字面量值;player這個Bean需要呼叫com.dream.Player類的staticFactory靜態工廠方法進行創建,而且呼叫的時候需要注入music這個Bean參考,
實體工廠方法注入
工廠方法除了靜態工廠方法,還有實體工廠方法,如果我們希望通過實體工廠方法創建Bean,只需向組態檔提供一些資訊,告訴Spring容器呼叫某個Bean的實體工廠方法完成Bean的創建與裝配即可,
因此,假如com.dream包現有這樣一些類:
1 public class Music { 2 private String musicName = null; 3 4 public Music() { 5 } 6 7 public Music(String musicName) { 8 this.musicName = musicName; 9 } 10 11 public Music instanceFactory(String musicName) { 12 return new Music(musicName); 13 } 14 }
1 public class Player { 2 private Music playingMusic = null; 3 4 public Player() { 5 } 6 7 public Player(Music playingMusic) { 8 this.playingMusic = playingMusic; 9 } 10 11 public Player instanceFactory(Music playingMusic) { 12 return new Player(playingMusic); 13 } 14 }
則可這樣配置Bean:
1 <beans /* 省略命名空間和XSD模式檔案宣告 */> 2 <bean id="music_1" class="com.dream.Music"/> 3 <bean id="music_2" factory-bean="music_1" factory-method="instanceFactory"> 4 <constructor-arg type="java.lang.String" value="執著"/> 5 </bean> 6 7 <bean id="player_1" class="com.dream.Player"/> 8 <bean id="player_2" factory-bean="player_1" factory-method="instanceFactory"> 9 <constructor-arg type="com.dream.Music" ref="music_2"/> 10 </bean> 11 </beans>
這里配置了四個Bean:music_1,music_2,player_1,player_2,其中,music_2,player_2就是通過實體工廠方法創建的,
配置實體工廠方法時,需用factory-method屬性指定實體工廠方法,factory-bean屬性指定實體工廠方法所屬的Bean,<constructor-arg>元素指定實體工廠方法所需的引數,當然,如果實體工廠方法創建的Bean存在屬性,也可通過<property>元素指定依賴注入,
因此,這段配置用于告訴Spring容器:music_2這個Bean需要呼叫music_1這個Bean的instanceFactory實體工廠方法進行創建,而且呼叫的時候需要注入“執著”這個字面量值;player_2這個Bean需要呼叫player_1這個Bean的instanceFactory實體工廠方法進行創建,而且呼叫的時候需要注入music_2這個Bean參考,
NULL值注入
NULL值的注入可用<null>元素進行描述,如下所示:
1 <bean id="player_1" class="com.dream.Player"> 2 <constructor-arg type="com.dream.Music"> 3 <null /> 4 </constructor-arg> 5 </bean>
1 <bean id="player_2" class="com.dream.Player"> 2 <property name="playingMusic"> 3 <null /> 4 </property> 5 </bean>
集合注入
Java提供了多種型別的集合,常見的有List,Set,Map,等等,自然而然的,Spring提供了些支持,用于配置集合的注入,
因此,假如com.dream包現有這樣一些類:
1 public class Music { 2 private List<String> musicNameList = null; 3 4 public List<String> getMusicNameList() { 5 return this.musicNameList; 6 } 7 8 public void setMusicNameList(List<String> musicNameList) { 9 this.musicNameList = musicNameList; 10 } 11 }
1 public class Player { 2 private List<Music> playingMusicList = null; 3 4 public List<Music> getPlayingMusicList() { 5 return this.playingMusicList; 6 } 7 8 public void setPlayingMusicList(List<Music> playingMusicList) { 9 this.playingMusicList = playingMusicList; 10 } 11 }
則可這樣配置Bean:
1 <beans /* 省略命名空間和XSD模式檔案宣告 */> 2 <bean id="music_1" class="com.dream.Music"/> 3 <bean id="music_2" class="com.dream.Music"> 4 <property name="musicNameList"> 5 <list> 6 <value>執著</value> 7 <value>一生有你</value> 8 </list> 9 </property> 10 </bean> 11 <bean id="player" class="com.dream.Player"> 12 <property name="playingMusicList"> 13 <list> 14 <ref bean="music_1"/> 15 <ref bean="music_2"/> 16 </list> 17 </property> 18 </bean> 19 </beans>
可以看到List型別的集合能用<list>元素配置,底下有個<value>元素,用于配置字面量值集合;有個<ref>元素,用于配置Bean參考集合,這些大家一看便知,不必詳述,重點在于,Spring是否也提供了諸如p-命名空間,c-命名空間之類的替代方案,用于簡化集合的配置呢?
當然有的,要知道p-命名空間,c-命名空間是不支持集合的,因此,Spring在spring-util.xsd模式檔案里定義了些XML元素,用于描述諸如集合之類的創建資訊,而這,需要引入spring-util.xsd模式檔案之后修改如下:
1 <beans /* 省略命名空間和XSD模式檔案宣告 */ 2 xmlns:util="http://www.springframework.org/schema/util" 3 xsi:schemaLocation=" 4 /* 省略命名空間和XSD模式檔案宣告 */ 5 http://www.springframework.org/schema/util 6 http://www.springframework.org/schema/util/spring-util.xsd"> 7 8 <bean id="music_1" class="com.dream.Music" /> 9 <bean id="music_2" class="com.dream.Music"> 10 <property name="musicNameList" ref="utilMusicNameList"/> 11 </bean> 12 <bean id="player" class="com.dream.Player"> 13 <property name="playingMusicList" ref="utilPlayingMusicList" /> 14 </bean> 15 16 <util:list id="utilMusicNameList"> 17 <value>執著</value> 18 <value>一生有你</value> 19 </util:list> 20 <util:list id="utilPlayingMusicList"> 21 <ref bean="music_1" /> 22 <ref bean="music_2" /> 23 </util:list> 24 25 </beans>
可以看到spring-util.xsd模式檔案定義了<util:list>元素,用于配置如何創建List型別的集合,底下有個<value>元素,用于配置字面量值集合;有個<ref>元素,用于配置Bean參考集合,因此,這段配置創建了兩個List型別的集合:一個集合的id是utilMusicNameList;一個集合的id是utilPlayingMusicList,之后,把集合utilMusicNameList注入music_2的musicNameList屬性,把集合utilPlayingMusicList注入player的playingMusicList屬性,完成集合的注入,
假如com.dream包現有這樣一些類:
1 public class Music { 2 private Set<String> musicNameSet = null; 3 4 public Set<String> getMusicNameSet() { 5 return this.musicNameSet; 6 } 7 8 public void setMusicNameSet(Set<String> musicNameSet) { 9 this.musicNameSet = musicNameSet; 10 } 11 }
1 public class Player { 2 private Set<Music> playingMusicSet = null; 3 4 public Set<Music> getPlayingMusicSet() { 5 return this.playingMusicSet; 6 } 7 8 public void setPlayingMusicSet(Set<Music> playingMusicSet) { 9 this.playingMusicSet = playingMusicSet; 10 } 11 }
則可這樣配置Bean:
1 <beans /* 省略命名空間和XSD模式檔案宣告 */> 2 <bean id="music_1" class="com.dream.Music" /> 3 <bean id="music_2" class="com.dream.Music"> 4 <property name="musicNameSet"> 5 <set> 6 <value>執著</value> 7 <value>一生有你</value> 8 </set> 9 </property> 10 </bean> 11 <bean id="player" class="com.dream.Player"> 12 <property name="playingMusicSet"> 13 <set> 14 <ref bean="music_1" /> 15 <ref bean="music_2" /> 16 </set> 17 </property> 18 </bean> 19 </beans>
可以看到Set型別的集合能用<set>元素配置,底下有個<value>元素,用于配置字面量值集合;有個<ref>元素,用于配置Bean參考集合,這些大家一看便知,不必詳述,重點在于,Set型別的集合同樣也能使用util元素進行配置,如下所示:
1 <beans /* 省略命名空間和XSD模式檔案宣告 */ 2 xmlns:util="http://www.springframework.org/schema/util" 3 xsi:schemaLocation=" 4 /* 省略命名空間和XSD模式檔案宣告 */ 5 http://www.springframework.org/schema/util 6 http://www.springframework.org/schema/util/spring-util.xsd"> 7 8 <bean id="music_1" class="com.dream.Music" /> 9 <bean id="music_2" class="com.dream.Music"> 10 <property name="musicNameSet" ref="utilMusicNameSet"/> 11 </bean> 12 <bean id="player" class="com.dream.Player"> 13 <property name="playingMusicSet" ref="utilPlayingMusicSet" /> 14 </bean> 15 16 <util:set id="utilMusicNameSet"> 17 <value>執著</value> 18 <value>一生有你</value> 19 </util:set> 20 <util:set id="utilPlayingMusicSet"> 21 <ref bean="music_1" /> 22 <ref bean="music_2" /> 23 </util:set> 24 25 </beans>
可以看到spring-util.xsd模式檔案定義了<util:set>元素,用于配置如何創建Set型別的集合,底下有個<value>元素,用于配置字面量值集合;有個<ref>元素,用于配置Bean參考集合,因此,這段配置創建了兩個Set型別的集合:一個集合的id是utilMusicNameSet;一個集合的id是utilPlayingMusicSet,之后,把集合utilMusicNameSet注入music_2的musicNameSet屬性,把集合utilPlayingMusicSet注入player的playingMusicSet屬性,完成集合的注入,
假如com.dream包現有這樣一些類:
1 public class Music { 2 private Map<String, String> musicNameMap = null; 3 4 public Map<String, String> getMusicNameMap() { 5 return this.musicNameMap; 6 } 7 8 public void setMusicNameMap(Map<String, String> musicNameMap) { 9 this.musicNameMap = musicNameMap; 10 } 11 }
1 public class Player { 2 private Map<Music, Music> playingMusicMap = null; 3 4 public Map<Music, Music> getPlayingMusicMap() { 5 return this.playingMusicMap; 6 } 7 8 public void setPlayingMusicMap(Map<Music, Music> playingMusicMap) { 9 this.playingMusicMap = playingMusicMap; 10 } 11 }
則可這樣配置Bean:
1 <beans /* 省略命名空間和XSD模式檔案宣告 */> 2 <bean id="music_1" class="com.dream.Music" /> 3 <bean id="music_2" class="com.dream.Music"> 4 <property name="musicNameMap"> 5 <map> 6 <entry key="執著" value="執著" /> 7 <entry key="一生有你" value="一生有你" /> 8 </map> 9 </property> 10 </bean> 11 <bean id="player" class="com.dream.Player"> 12 <property name="playingMusicMap"> 13 <map> 14 <entry key-ref="music_1" value-ref="music_1" /> 15 <entry key-ref="music_2" value-ref="music_2" /> 16 </map> 17 </property> 18 </bean> 19 </beans>
可以看到Map型別的集合能用<map>元素和<entry>元素配置,<entry>元素有個key屬性,用于配置字面量值的字典鍵;有個key-ref屬性,用于配置Bean參考的字典鍵;有個value屬性,用于配置字面量值的字典值;有個value-ref屬性,用于配置Bean參考的字典值,這些大家一看便知,不必詳述,重點在于,Map型別的集合同樣也能使用util元素進行配置,如下所示:
1 <beans /* 省略命名空間和XSD模式檔案宣告 */ 2 xmlns:util="http://www.springframework.org/schema/util" 3 xsi:schemaLocation=" 4 /* 省略命名空間和XSD模式檔案宣告 */ 5 http://www.springframework.org/schema/util 6 http://www.springframework.org/schema/util/spring-util.xsd"> 7 8 <bean id="music_1" class="com.dream.Music" /> 9 <bean id="music_2" class="com.dream.Music"> 10 <property name="musicNameMap" ref="utilMusicNameMap"/> 11 </bean> 12 <bean id="player_1" class="com.dream.Player"> 13 <property name="playingMusicMap" ref="utilPlayingMusicMap" /> 14 </bean> 15 16 <util:map id="utilMusicNameMap"> 17 <entry key="執著" value="執著" /> 18 <entry key="一生有你" value="一生有你" /> 19 </util:map> 20 <util:map id="utilPlayingMusicMap"> 21 <entry key-ref="music_1" value-ref="music_1" /> 22 <entry key-ref="music_2" value-ref="music_2" /> 23 </util:map> 24 25 </beans>
可以看到spring-util.xsd模式檔案定義了<util:map>元素,用于配置如何創建Map型別的集合,底下有個<entry>元素,用于配置字典集合的鍵值對,因此,這段配置創建了兩個Map型別的集合:一個集合的id是utilMusicNameMap;一個集合的id是utilPlayingMusicMap,之后,把集合utilMusicNameMap注入music_2的musicNameMap屬性,把集合utilPlayingMusicMap注入player的playingMusicMap屬性,完成集合的注入,
延遲裝配
按照正常流程,Spring容器完成Bean的創建之后,開始通過Bean的屬性注入Bean的依賴,完成Bean的裝配,可是有時候,我們并不希望Spring容器完成Bean的創建之后立即注入依賴,而是希望等到用到的時候才開始注入,這時,就需要用到延遲裝配,告訴Spring容器等到用到Bean的時候,才開始注入Bean所需的依賴,如下所示:
1 <beans /* 省略命名空間和XSD模式檔案宣告 */> 2 <bean id="music" class="com.dream.Music" lazy-init="true"> 3 <property name="musicName" value="執著"/> 4 </bean> 5 <bean id="player" class="com.dream.Player" lazy-init="true"> 6 <property name="playingMusic" ref="music"/> 7 </bean> 8 </beans>
這段配置用到<bean>元素的lazy-init屬性,用于告訴Spring容器需不需要延遲Bean的裝配,如果lazy-init屬性等于true,Spring容器創建Bean之后,只會等到用到Bean的時候才開始注入依賴;如果lazy-init屬性等于false,Spring容器創建Bean之后,就會立即開始注入依賴,lazy-init屬性默認等于false,這里,我們把lazy-init屬性設為true,告訴Spring容器延遲裝配music和player這兩個Bean所需的依賴,
另外,我們還可設定根元素<beans>的default-lazy-init屬性,告訴Spring容器所有的Bean都要延遲裝配,如下所示:
1 <beans default-lazy-init="true" 2 /* 省略命名空間和XSD模式檔案宣告 */> 3 <bean id="music" class="com.dream.Music"> 4 <property name="musicName" value="執著"/> 5 </bean> 6 <bean id="player" class="com.dream.Player"> 7 <property name="playingMusic" ref="music"/> 8 </bean> 9 </beans>
指定ID
一直以來,我們都用<bean>元素的id屬性指定Bean的唯一識別符號,可是我們不知道的是,除了id屬性,我們也能使用name屬性配置同樣的資訊,如下所示:
1 <bean id="music_1" name="music_2,music_3,music_4" class="com.dream.Music"/>
我們指定id屬性的值為music_1,指定name屬性的值為 music_2,music_3,music_4 ,因此,該Bean具有四個唯一識別符號:music_1,music_2,music_3和music_4,同時我們也注意到了,id屬性和name屬性有個重大差別:id屬性只能指定一個唯一識別符號;name屬性則不同,可以同時指定多個唯一識別符號,識別符號之間只要使用逗號,分號或空格隔開就行,
除此之外,Spring還提供了<alias>元素,用于指定Bean的別名,如下所示:
1 <bean id="music_1" class="com.dream.Music"/> 2 <alias name="music_1" alias="music_2" />
<alias>元素具有name和alias兩個屬性:name屬性用于指定Bean的唯一識別符號;alias屬性用于指定Bean的別名,因此,這段配置能夠告訴Spring容器,給id為music_1的Bean起個別名music_2,之后,我們既可使用music_1,也可使用music_2參考該Bean
至此,我們完成了關于如何配置Bean的更多介紹,下章該談談自動裝配時,Bean的歧義應該如何解決那些事了,歡迎大家繼續閱讀,謝謝大家!
回傳目錄 下載代碼
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/423232.html
標籤:其他
上一篇:快慢指標的妙用
