一、選題的背景 (1)為什麼要選擇此選題? 樂高是一個很受歡迎的玩具積木品牌,它們通常是成套出售的,用來製作特定的物品,每一套都包含許多不同形狀、大小和顏色的零件。它是一個有趣的數據集合,它包含了多年來集合的綜合列表,以及每個集合包含的部分數。提供了許多可供探索的空間,特別是因為“集合”文件包含了集 ...
3.depends-on
(1) depends-on用來表示一個bean的實例化依靠另一個bean的先實例化,如果在一個bean A上定義了depends-on bean B就表示:bean A實例化前先實例化bean B。
<!-- 例一 -->
<beans ...>
<!-- 對於下麵這倆個bean,誰先誰後創建不能確定 -->
<bean id="exampleA" class="cn.example.spring.boke.ExampleA"></bean>
<bean id="exampleB" class="cn.example.spring.boke.ExampleB"></bean>
</beans>
<!-- 例二 -->
<beans ...>
<!-- exampleB depends-on exampleA,因此exampleA會先於exampleB被創建 -->
<bean id="exampleA" class="cn.example.spring.boke.ExampleA"></bean>
<bean id="exampleB" class="cn.example.spring.boke.ExampleB" depends-on="exampleA"></bean>
</beans>
4.懶載入
(1) 預設情況下,Spring會在容器啟動時初始化所有的singleton bean,因為在這種情況下,某些配置錯誤會儘早發現,但如果我們不想提前初始化bean,就可以指定bean的lazy-init屬性,來延遲初始化bean,這樣這個bean會在第一次請求時被初始化而非在容器啟動時被初始化
<beans ...>
<!-- exampleA會在第一次請求時被初始化 -->
<bean id="exampleA" class="cn.example.spring.boke.ExampleA" lazy-init="true"></bean>
<!-- exampleB會在容器啟動時被初始化 -->
<bean id="exampleB" class="cn.example.spring.boke.ExampleB"></bean>
</beans>
(2) 註意:當延遲初始化的bean是非延遲初始化的bean的依賴項時,延遲初始化就失效了,它也會在容器啟動時被初始化,因為容器在啟動時必須為這個非延遲初始化的bean註入依賴項
(3) 使用beans標簽上的default-lazy-init屬性批量設置延遲初始化的bean
<beans default-lazy-init="true">
<!-- 相當於給容器內的每一個bean都提供了lazy-init=true屬性 -->
</beans>
4.自動裝配
(1) 對於存在依賴關係的多個bean,我們可以通過ref屬性來手動註入依賴項,同時,如果不想手動,可通過設置bean標簽的autowire屬性來開啟Spring的自動裝配功能,它會按照所給的策略來自動的註入依賴項,相較於手動裝配,其具有自動更新配置,簡化代碼等優點,如下
<!-- 例一:手動裝配 -->
<beans ...>
<bean id="exampleA" class="cn.example.spring.boke.ExampleA"></bean>
<bean id="exampleB" class="cn.example.spring.boke.ExampleB">
<!-- 使用ref來配置依賴項 -->
<property name="exampleA" ref="exampleA"></property>
</bean>
</beans>
<!-- 例二:自動裝配 -->
<beans ...>
<bean id="exampleA" class="cn.example.spring.boke.ExampleA"></bean>
<!-- autowire屬性設置為byType,告訴容器來按照類型進行依賴項的註入 -->
<bean id="exampleB" class="cn.example.spring.boke.ExampleB" autowire="byType"></bean>
</beans>
(2) 自動裝配策略,即autowire屬性的取值:
策略 | 描述 |
---|---|
no | 預設選項,即不進行自動裝配,bean之間的依賴關係通過指定ref屬性來手動裝配 |
byName | 根據屬性名稱進行自動裝配,Spring會尋找與屬性名同名的bean來進行裝配,比如上面的例子中,exampleB對象有一個名為exampleA的成員變數,則Spring會在容器中尋找id為exampleA的這個bean進行註入 |
byType | 根據屬性類型進行自動裝配,如果容器中恰好存在一個同類型的bean,則會進行自動裝配,如果存在多個,則會拋出異常,如果沒有該類型的bean,則什麼也不會發生,屬性不會被註入 |
constructor | 類似於byType,不過針對的是構造函數參數進行的自動裝配,如果容器中不存在類型跟構造函數參數的類型一樣的bean時,將引發異常 |
此外,可通過byType或constructor策略,來對數組或集合進行自動裝配,註入與類型相匹配的所有bean,如下
public class ExampleA {}
//ExampleB中存在一個類型為ExampleA的集合,希望通過這個集合來接收容器內所有類型為ExampleA的bean
public class ExampleB {
private List<ExampleA> exampleAList;
public void setExampleAList(List<ExampleA> exampleAList) {
this.exampleAList = exampleAList;
}
}
<!-- xml配置文件 -->
<beans ...>
<!-- 定義了兩個類型為ExampleA的bean -->
<bean id="exampleA1" class="cn.example.spring.boke.ExampleA"></bean>
<bean id="exampleA2" class="cn.example.spring.boke.ExampleA"></bean>
<!-- autowire為byType,此時Spring會向exampleAList中註入上面定義的兩個bean -->
<bean id="exampleB" class="cn.example.spring.boke.ExampleB" autowire="byType"></bean>
</beans>
(3) 自動裝配的缺陷:
-
在property或constructor-arg標簽中手動指定的bean會覆蓋掉自動裝配的bean,此外,自動裝配不同裝配一些簡單類型,如int,boolean,String等
-
自動裝配不如手動顯式指定精確
-
如果容器中存在同一類型的多個bean時,由於容器有時不知道該裝配哪一個,從而會引發異常(解決方案:1.放棄自動裝配改為手動裝配 2.將不期望裝配的bean的autowire-candidate屬性設為false,容器在尋找依賴項時會忽略掉這個bean 3.將期望裝配的bean的primary屬性設為true,容器會首先裝配這個bean)
(4) 在自動裝配過程中排除bean:通過bean標簽中的autowire-candidate屬性(該屬性只會影響byType策略,對於byName無效),來設置當前bean在自動裝配過程中是否作為候選bean,預設值為true,當設置為false時,表示當前bean不作為候選bean,即容器在尋找依賴項時會忽略掉這個bean,例子如下
public class ExampleA {}
//ExampleB依賴ExampleA
public class ExampleB {
private ExampleA exampleA;
public void setExampleAList(ExampleA exampleA) {
this.exampleA = exampleA;
}
}
<!-- xml配置文件 -->
<beans ...>
<!-- 如果這裡不將exampleA1的autowire-candidate屬性設置為false,那麼容器中就會有兩個類型為ExampleA的bean,在自動裝配時,容器會拋出NoUniqueBeanDefinitionException -->
<!-- exampleA1的autowire-candidate為false,那麼容器在尋找依賴項時就會忽略這個bean,因此會將exampleA2進行註入 -->
<bean id="exampleA1" class="cn.example.spring.boke.ExampleA" autowire-candidate="false"></bean>
<bean id="exampleA2" class="cn.example.spring.boke.ExampleA"></bean>
<bean id="exampleB" class="cn.example.spring.boke.ExampleB" autowire="byType"></bean>
</beans>