1Spring自動裝配的分類
Spring能自動裝配Bean與Bean之間的依賴關係,即無須使用ref顯式地指定依賴Bean,而是由Spring容器檢查XML配置文件內容。根據某種規則,爲調用者Bean注入被依賴的Bean。
Spring的自動裝配可以通過<beans../>元素的default-autowire屬性指定,該屬性對配置文件中所有的Bean起作用;也可以通過<bean>元素的autowire屬性指定,該屬性只對當前bean起作用。
自動裝配可以減少配置文件的工作量,但是降低了依賴關係的透明性和確定性。
自動裝配分爲如下幾種類型:
- no :不使用自動裝配。Bean依賴關係完全由ref元素定義。這是默認的配置,在較大的部署環境中不鼓勵改變這個配置,顯示配置合作者能夠得到更清晰的關係。
- byName:根據setter名字進行自動裝配。Spring容器查找容器中的全部Bean,找出其id與setter方法名去掉set前綴,並小寫首字母后同名的Bean來完成注入。如果沒有找到匹配的Bean實例,不會進行注入。
- byType:根據setter方法的形參類型來自動裝配。Spring容器查找容器中的全部Bean,如果有一個Bean類型與setter類型匹配,就自動注入這個Bean,如果找到多個,就拋出異常;如果沒有找到,不會發生注入。
- constructor:與byType類似,區別是用於自動匹配構造器的參數。如果容器找不到適配的構造器,拋出一個異常
- autodect:Spring容器根據Bean內部結構,自定決定使用constructor或byType策略。如果找到一個默認的構造函數,那麼就會應用byType策略。
2 byName
定義兩個類,A,B,A類中包含一個setXiaoB()方法,spring配置文件中定義一個id爲xiaoB的Bean,Spring會爲其自動注入
(1) 類 A,B
class A
{
private B xiaoB;
public void setXiaoB(B xiaoB)
{
System.out.println("A注入B");
this.xiaoB = xiaoB;
}
}
class B
{
}
(2) 配置文件
<bean id="xiaoA" class="com.songxu.autowire.A" autowire="byName">
</bean>
<bean id="xiaoB" class="com.songxu.autowire.B" >
</bean>
結果注入成功,對於這種注入來說,Spring僅僅會根據名字去查找,即使類型不匹配也會發生注入,只是在注入的時候拋出類型轉換異常。
3 byType
還是利用上面的A,B類,僅僅修改一下配置文件
<bean id="xiaoA" class="com.songxu.autowire.A" autowire="byType">
</bean>
<bean id="B" class="com.songxu.autowire.B" >
</bean>
這時spring將自動完成byType的注入。如果同時定義了多個B類型的Bean的話,就會拋出No unique bean of type [com.songxu.autowire.B] is defined:異常。對於這種情況的解決,可以設置autowire-candidate屬性,設置autowire-candidate="false",即可將該bean排除在autowire之外。
4 constructor
這種方法不是很常用。定義A類,並利用構造方法初始化屬性xiaoB。
class A
{
private B xiaoB;
public void setXiaoB(B xiaoB)
{
System.out.println("A注入B");
this.xiaoB = xiaoB;
}
public A(B xiaoB)
{
System.out.println("構造xiaoB");
this.xiaoB=xiaoB;
}
public A()
{
System.out.println("默認構造A");
}
}
class B
{
}
配置文件
<bean id="xiaoA" class="com.songxu.autowire.A" autowire="constructor">
</bean>
<bean id="B" class="com.songxu.autowire.B" >
</bean>
這個時候在A初始化的時候,將把xiaoB通過構造方法自動注入。這裏需要注意的時候,它是一種依照類型查找的方式,如果在配置文件中定義了多個B類型的Bean,將不會觸發這種注入方式,而是使用默認的構造方法構造A對象。
對於上面介紹的三種方式,如果指定了ref屬性,那麼所有自動裝配都將失效。
5 集合的自動裝配
對於數組和集合類型的自動裝配,僅能自動裝配接口類型,而不能是他們的實現類。對於這個原因,可參考這篇博客。
下面一個例子
(1)Bean的定義
public class A
{
//private B xiaoB;
private List<B> list;
/*private B getXiaoB()
{
return xiaoB;
}
public void setXiaoB(B xiaoB)
{
System.out.println("xiaoB注入 ");
this.xiaoB = xiaoB;
}*/
public List<B> getList()
{
return list;
}
//此處設置 list 與ArrayList是有區別的
public void setList(List<B> list)
{
this.list = list;
}
}
(2)配置文件
<bean id="xiaoA" class="com.songxu.autowire.A" autowire="byType">
</bean>
<bean id="xiaoB" class="com.songxu.autowire.B" ></bean>
<bean id="xiaoB2" class="com.songxu.autowire.B" ></bean>
<bean id="xiaoB3" class="com.songxu.autowire.B" ></bean>
<bean id="xiaoB4" class="com.songxu.autowire.B" ></bean>
<bean id="xiaoB5" class="com.songxu.autowire.B" ></bean>
<bean id="xiaoB6" class="com.songxu.autowire.B" ></bean>
<bean id="xiaoB7" class="com.songxu.autowire.B" ></bean>