Spring3系列8- Spring 自動裝配 Bean
1. Auto-Wiring ‘no’
2. Auto-Wiring ‘byName’
3. Auto-Wiring ‘byType
4. Auto-Wiring ‘constructor’
5. Auto-Wiring ‘autodetect’
Spring Auto-Wiring Beans——Spring自動裝配Bean
所謂自動裝配,就是將一個Bean注入到其他Bean的Property中,類似於以下:
<bean id="customer" class="com.lei.common.Customer" autowire="byName" />
Spring支持5種自動裝配模式,如下:
no ——默認情況下,不自動裝配,通過“ref”attribute手動設定。
buName ——根據Property的Name自動裝配,如果一個bean的name,和另一個bean中的Property的name相同,則自動裝配這個bean到Property中。
byType ——根據Property的數據類型(Type)自動裝配,如果一個bean的數據類型,兼容另一個bean中Property的數據類型,則自動裝配。
constructor ——根據構造函數參數的數據類型,進行byType模式的自動裝配。
autodetect ——如果發現默認的構造函數,用constructor模式,否則,用byType模式。
下例中演示自動裝配
Customer.java如下:
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如下:
package com.lei.common; public class Person { //... }
1. Auto-Wiring ‘no’
默認情況下,需要通過'ref’來裝配bean,如下:
<bean id="customer" class="com.lei.common.Customer"> <property name="person" ref="person" /> </bean> <bean id="person" class="com.lei.common.Person" />
2. Auto-Wiring ‘byName’
根據屬性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。
3. Auto-Wiring ‘byType
根據屬性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。
4. Auto-Wiring ‘constructor’
這種情況下,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中。我更願意寫配置文件來手工裝配。