spring的自動裝配(default-autowire="byName")
自動裝配,官方給出的定義是這樣:
Spring IoC容器可以自動裝配(autowire)相互協作bean之間的關聯關係。因此,如果可能的話,可以自
動讓Spring通過檢查BeanFactory中的內容,來替我們指定bean的協作者(其他被依賴的bean)。由於
autowire可以針對單個bean進行設定,因此可以讓有些bean使用autowire,有些bean不採用。autowire的
方便之處在減少或者消除屬性或構造器引數的設定,這樣可以給我們的配置檔案減減肥
其實,自動裝配就是讓我們少些幾個 <ref ="...">.
我們還是從需求出發.我們假設有4個bean.分別是bean2,bean3,bean4,bean5..其中,bean2裡面有後面幾個
的引用..我只放出來bean2.java.
package com.test.model;
public class Bean2 {
private Bean3 bean3;
private Bean4 bean4;
private Bean5 bean5;
public Bean3 getBean3() {
return bean3;
}
public void setBean3(Bean3 bean3) {
this.bean3 = bean3;
}
public Bean4 getBean4() {
return bean4;
}
public void setBean4(Bean4 bean4) {
this.bean4 = bean4;
}
public Bean5 getBean5() {
return bean5;
}
public void setBean5(Bean5 bean5) {
this.bean5 = bean5;
}
}
我們看不用自動裝配的寫法
<bean id="bean2" class="com.test.model.Bean2">
<property name="bean3" ref="bean3"/>
<property name="bean4">
<ref bean="bean4"/>
</property>
<property name="bean5" ref="bean5"/>
</bean>
很明顯,下面的幾個屬性設定是很繁瑣的..我們假設使用自動裝配.我們只需要這樣
<bean id="bean2" class="com.test.model.Bean2" />
裡面的裝配都不用寫.
當然,自動裝配必須滿足兩點
(1)bean2.java裡面的屬性名字必須和applicationContext.xml裡面對應的bean id的名字相同..也就是
private Bean3 bean3; 這個bean3(其實對應的是get,set方法)必須和
<bean id="bean3" class="com.test.model.Bean3"
parent="abstractBean">
<property name="name" value="Tom" />
<property name="password" value="123" />
</bean> 這個bean3相同.否則不能自動裝配
(2)在申明裡配置一個屬性.default-autowire="byName"(通過名字自動裝配)
配置檔案為.
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd"
default-autowire="byName">
<bean id="abstractBean" abstract="true">
<property name="id">
<value>1000</value>
</property>
<property name="name" value="java" />
</bean>
<bean id="bean2" class="com.test.model.Bean2" />
<bean id="bean3" class="com.test.model.Bean3"
parent="abstractBean">
<property name="name" value="Tom" />
<property name="password" value="123" />
</bean>
<bean id="bean4" class="com.test.model.Bean4" parent="abstractBean" />
<bean id="bean5" class="com.test.model.Bean5">
<property name="age" value="20" />
</bean>
default-autowire="x"
x有4個選擇:byName,byType,constructor和autodetect
1. byName:
Service.java
public class Service
{
Source source;
public void setSource(Source source)
{
this.source = source;
}
}
applicationContext.xml
<beans
...
default-autowire="byName">
<bean id="source" class="cn.hh.spring.DBCPSource" scope="prototype"/>
<bean id="service" class="cn.hh.spring.Service" scope="prototype">
</bean>
</beans>
cn.hh.spring.DBCPSource實現了Source介面
xml中並沒有給 bean service配Source屬性,但在beans中設定了autowire="byName",這樣配置檔案會自
動根據 cn.hh.spring.Service 中的setSource找bean id="Source"的bean ,然後自動配上去,如果沒找
到就不裝配。
注意:byName的name是java中setXxxx 的Xxxx, 和上面設定的Source source中source拼寫毫無關係,完
全可以是
public class Service
{
Source source1;
public void setSource(Source source1)
{
this.source1 = source1;
}
}
2. byType:
Service.java同上
applicationContext.xml
<beans
...
default-autowire="byType">
<bean id="dbcpSource" class="cn.hh.spring.DBCPSource" scope="prototype"/>
<bean id="service" class="cn.hh.spring.Service" scope="prototype">
</bean>
</beans>
同樣沒有配置setSource,autowire改成 "byType",配置檔案會找實現了Source介面的bean,這裡
cn.hh.spring.DBCPSource 實現了Source介面,所以自動裝配,如果沒找到則不裝配。
如果同個配製檔案中兩個bean實現了Source介面,則報錯。
這裡的 Type是指setSource(Source source)中引數的型別。
3. constructor:
試圖在容器中尋找與需要自動裝配的bean的建構函式引數一致的一個或多個bean,如果沒找到則丟擲異常
。
4. autodetect:
首先嚐試使用constructor來自動裝配,然後再使用byType方式。