所謂自動裝配,就是將一個Bean注入到其餘Bean的Property中,相似於如下:java
<bean id="customer" class="com.lei.common.Customer" autowire="byName" />
Spring支持5種自動裝配模式,以下:spring
no ——默認狀況下,不自動裝配,經過「ref」attribute手動設定。函數
buName ——根據Property的Name自動裝配,若是一個bean的name,和另外一個bean中的Property的name相同,則自動裝配這個bean到Property中。this
byType ——根據Property的數據類型(Type)自動裝配,若是一個bean的數據類型,兼容另外一個bean中Property的數據類型,則自動裝配。code
constructor ——根據構造函數參數的數據類型,進行byType模式的自動裝配。blog
autodetect ——若是發現默認的構造函數,用constructor模式,不然,用byType模式。開發
下例中演示自動裝配io
Customer.java以下:class
package com.lei.common; public class Customer { private Person person; public Customer(Person person) { this.person = person; } public void setPerson(Person person) { this.person = person; } //... }
Person.java以下:thread
package com.lei.common; public class Person { //... }
默認狀況下,須要經過'ref’來裝配bean,以下:
<bean id="customer" class="com.lei.common.Customer"> <property name="person" ref="person" /> </bean> <bean id="person" class="com.lei.common.Person" />
根據屬性Property的名字裝配bean,這種狀況,Customer設置了autowire="byName",Spring會自動尋找與屬性名字「person」相同的bean,找到後,經過調用setPerson(Person person)將其注入屬性。
<bean id="customer" class="com.lei.common.Customer" autowire="byName" /> <bean id="person" class="com.lei.common.Person" />
若是根據 Property name找不到對應的bean配置,以下
<bean id="customer" class="com.lei.common.Customer" autowire="byName" /> <bean id="person_another" class="com.lei.common.Person" />
Customer中Property名字是person,可是配置文件中找不到person,只有person_another,這時就會裝配失敗,運行後,Customer中person=null。
根據屬性Property的數據類型自動裝配,這種狀況,Customer設置了autowire="byType",Spring會總動尋找與屬性類型相同的bean,找到後,經過調用setPerson(Person person)將其注入。
<bean id="customer" class="com.lei.common.Customer" autowire="byType" /> <bean id="person" class="com.lei.common.Person" />
若是配置文件中有兩個類型相同的bean會怎樣呢?以下:
<bean id="customer" class="com.lei.common.Customer" autowire="byType" /> <bean id="person" class="com.lei.common.Person" /> <bean id="person_another" class="com.lei.common.Person" />
一旦配置如上,有兩種相同數據類型的bean被配置,將拋出UnsatisfiedDependencyException異常,見如下:
Exception in thread "main" org.springframework.beans.factory.UnsatisfiedDependencyException:
因此,一旦選擇了’byType’類型的自動裝配,請確認你的配置文件中每一個數據類型定義一個惟一的bean。
這種狀況下,Spring會尋找與參數數據類型相同的bean,經過構造函數public Customer(Person person)將其注入。
<bean id="customer" class="com.lei.common.Customer" autowire="constructor" /> <bean id="person" class="com.lei.common.Person" />
這種狀況下,Spring會先尋找Customer中是否有默認的構造函數,若是有至關於上邊的’constructor’這種狀況,用構造函數注入,不然,用’byType’這種方式注入,因此,此例中經過調用public Customer(Person person)將其注入。
<bean id="customer" class="com.lei.common.Customer" autowire="autodetect" /> <bean id="person" class="com.lei.common.Person" />
注意:
項目中autowire結合dependency-check一塊兒使用是一種很好的方法,這樣可以確保屬性老是能夠成功注入。
<bean id="customer" class="com.lei.common.Customer" autowire="autodetect" dependency-check="objects" /> <bean id="person" class="com.lei.common.Person" />
最後,我認爲,自動裝配雖然讓開發變得更快速,可是同時卻要花更大的力氣維護,由於它增長了配置文件的複雜性,你甚至不知道哪個bean會被自動注入到另外一個bean中。我更願意寫配置文件來手工裝配。