自動裝配的幾種方式——Spring IOC/DI(四)
本章主要講解自動裝配的幾種方式,接上一章依賴注入的方式以及裝配屬性:
https://blog.csdn.net/qq_34598667/article/details/83308071
自動裝配之自動裝配的幾種方式
Spring 容器可以在不使用< constructor-arg >和< property > 元素的情況下自動裝配相互協作的 bean 之間的關係,助於減少編寫一個大的基於 Spring 的應用程式的 XML 配置的數量
使用< bean >元素的 autowire 屬性為一個 bean 定義指定自動裝配模式。
下面通過案例講解一下autowire的幾個值,代表自動裝配的幾種方式
案例準備:基於之前案例的實體類Person和Man
no
預設設定,沒有自動裝配
就不舉例了
byName:由屬性名自動裝配
將它的屬性與在配置檔案中被定義為相同名稱的 beans 的屬性進行連線。
定義applicationContext.xml檔案為:
<!-- setter注入 -->
<bean id="person" class="com.oak.entity.Person">
<property name="age" value="18"/>
<property name="name" value=" 二蛋"/>
</bean>
<!--byName 根據屬性名自動裝配 -->
<bean id="man" class="com.oak.entity.Man" autowire="byName"></bean>
在test類中新增test05方法並測試:
@Test
public void test05(){
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
Person person= ctx.getBean("person",Person.class);
System.out.println(person);
Man man=ctx.getBean("man",Man.class);
System.out.println(man);
}
檢視控制檯輸出:
Person [name=二蛋, age=18]
Man [person=Person [name=二蛋, age=18]]
裝配成功
Man的屬性person會自動找到id/name為person的bean,如果沒有定義為person的bean則裝配失敗,例如,修改xml中bean為person的名稱為person1:
<!-- setter注入 -->
<bean id="person1" class="com.oak.entity.Person">
<property name="age" value="18"/>
<property name="name" value="二蛋"/>
</bean>
<!--byName 根據屬性名自動裝配 -->
<bean id="man" class="com.oak.entity.Man" autowire="byName"></bean>
修改測試test05得到id為person1的bean,控制檯結果為
Person [name=二蛋, age=18]
Man [person=null]
自動裝配失敗
byType:由屬性資料型別自動裝配
它的型別匹配配置檔案中的一個確切的 bean 名稱,
直接修改配置檔案中的裝配型別為byType
<!--byType 根據屬性名自動裝配 -->
<bean id="man" class="com.oak.entity.Man" autowire="byType"></bean>
其他不用修改,直接測試test05方法:
控制檯結果為:
Person [name=二蛋, age=18]
Man [person=Person [name=二蛋, age=18]]
就算找不到與屬性名相同的bean也能裝配成功,因為是根據屬性型別查詢的。
但是當出現多個同一屬性的bean時會報異常,例如,修改xml檔案如下:
<!-- setter注入 -->
<bean id="person1" class="com.oak.entity.Person">
<property name="age" value="18"/>
<property name="name" value="二蛋"/>
</bean>
<!-- setter注入 -->
<bean id="person2" class="com.oak.entity.Person">
<property name="age" value="19"/>
<property name="name" value="二狗"/>
</bean>
<bean id="man" class="com.oak.entity.Man" autowire="byType"></bean>
繼續測試test05方法,Junit測試出異常
constructor:與byType類似,應用於建構函式
測試此方式時不要忘記在實體類中需要帶有bean引數型別的構造方法
public Man(Person person) {
super();
this.person = person;
}
修改xml配置檔案
<!-- setter注入 -->
<bean id="person1" class="com.oak.entity.Person">
<property name="age" value="18"/>
<property name="name" value="二蛋"/>
</bean>
<bean id="man" class="com.oak.entity.Man" autowire="constructor">
</bean>
測試test05方法,控制檯結果為:
Person [name=二蛋, age=18]
Man [person=Person [name=二蛋, age=18]]
constructor自動裝配具有和byType自動裝配相同的侷限性。當發現多個Bean匹配某個構造器的入參時,Spring不會嘗試猜測哪一個Bean更適合自動裝配,會裝配失敗。此外,如果一個類有多個構造器,它們都滿足自動裝配的條件時,Spring也不會嘗試猜測哪一個構造器更適合使用。
autodetect
Spring首先嚐試通過 constructor 使用自動裝配來連線,如果它不執行,Spring 嘗試通過 byType 來自動裝配。
如果想要自動裝配bean,但是又不能決定該使用哪一種型別的自動裝配,那麼可以設定autowire屬性為autodetect,由spring 來決定
就不舉例了~
下一章,基於註解的自動裝配(元件掃描):