1. 程式人生 > >自動裝配的幾種方式——Spring IOC/DI(四)

自動裝配的幾種方式——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 名稱,它將嘗試匹配和連線屬性的型別。如果有多個該型別的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 來決定
就不舉例了~


下一章,基於註解的自動裝配(元件掃描):