Spring容器可以自動連接協(xié)作bean之間的關(guān)系悲没。您可以通過檢查ApplicationContext的內(nèi)容讓Spring自動為您的bean解析協(xié)作者(其他bean)湖笨。自動裝配具有以下優(yōu)點(diǎn):
- 自動裝配可以顯著減少對指定屬性或構(gòu)造函數(shù)參數(shù)的需要问芬。(在本章其他地方討論的其他機(jī)制谊娇,如bean模板检访,在這方面也很有價值症革。)
- 自動裝配可以隨著對象的發(fā)展更新配置筐咧。例如,如果需要向類添加依賴項(xiàng)噪矛,則可以自動滿足該依賴項(xiàng)量蕊,而無需修改配置。因此艇挨,自動裝配在開發(fā)期間尤其有用残炮,而不會在代碼庫變得更穩(wěn)定時否定切換到顯式裝配的選項(xiàng)。
1. XML自動裝配
使用基于XML的配置元數(shù)據(jù)(請參閱依賴注入)時缩滨,可以使用<bean />元素的autowire屬性為bean定義指定autowire模式势就。自動裝配功能有四種模式辞居。下表描述了四種自動裝配模式:
Mode | Explanation |
---|---|
no | (默認(rèn))無自動裝配。Bean引用必須由ref元素定義蛋勺。不建議對較大的部署更改默認(rèn)設(shè)置瓦灶,因?yàn)槊鞔_指定協(xié)作者可以提供更好的控制和清晰度。在某種程度上抱完,它記錄了系統(tǒng)的結(jié)構(gòu)贼陶。(任然可以使用@Autowried 注解自動裝配) |
byName | 按屬性名稱自動裝配。 Spring查找與需要自動裝配的屬性同名的bean巧娱。例如碉怔,如果bean定義按名稱設(shè)置為autowire并且它包含master屬性(即,它具有setMaster(..)方法)禁添,則Spring會查找名為master的bean定義并使用它來設(shè)置屬性撮胧。如果未找到也不回報(bào)錯,這在運(yùn)行時可能會報(bào)空指針異常老翘。 |
byType | 如果容器中只存在一個屬性類型的bean芹啥,則允許屬性自動裝配。如果存在多個铺峭,則拋出致命異常墓怀,這表示您不能對該bean使用byType自動裝配。如果沒有匹配的bean卫键,則不會發(fā)生任何事情(該屬性未設(shè)置)傀履。如果未找到也不回報(bào)錯,這在運(yùn)行時可能會報(bào)空指針異常莉炉。 |
constructor | 類似于byType但適用于構(gòu)造函數(shù)參數(shù)钓账。如果容器中沒有構(gòu)造函數(shù)參數(shù)類型的一個bean,則會引發(fā)致命錯誤絮宁。 |
通過以上我們可以知道梆暮,如果你的依賴是必須依賴(一定要注入),則不要使用byType羞福,byName的方式自動裝配惕蹄,而是使用構(gòu)造方法自動裝配。因?yàn)闃?gòu)造方法自動裝配治专,會在啟動時就會報(bào)錯(找不到bean)卖陵。
org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type
2. 注解的自動裝配
使用注解的自動裝配,自動裝配的顆粒度更細(xì)张峰。我們可以使用@AutoWried
泪蔫,@Resource
(JSR-250),@Inject(需要javax.inject
包)
和xml不一樣的是基于注解的自動裝配喘批,如果找不到bean撩荣,會在啟動時報(bào)錯铣揉。而且@AutoWried
可以通過它的required
屬性來控制是否需要注入。
- @AutoWried
注入時使用在field餐曹,構(gòu)造器逛拱,方法。
一般情況下是基于類型自動裝配台猴。偶爾也可以通過名稱(不使用qualifier和primary)朽合。
有一種特殊情況,如果有兩個相同類型的候選bean饱狂,Spring會將注入點(diǎn)名稱(即field名稱或參數(shù)名稱)與目標(biāo)bean名稱進(jìn)行匹配曹步,然后選擇同名的候選人,如果有的話休讳。
- @Resource
注入時使用在field和方法上(只支持單個參數(shù))讲婚。
默認(rèn)是基于名稱自動裝配的。@Resource
自動裝配按以下順序裝配:
- 使用
@Resource
的name
屬性俊柔,例如:@Resource(name = "Bean1")筹麸; - 不使用
name
屬性,如果是加在field上Spring會根據(jù)field的名稱匹配婆咸,加在方法上Spring會根據(jù)set方法的名稱或set方法的參數(shù)名來匹配竹捉,例如,Bean的名稱是myBeanName尚骄,則以下示例都能成功匹配:
@Resource
private MyBeanName myBeanName;
-----------------------------------------------------------------------
@Resource
private MyBeanName myBeanName22;//根據(jù)類型匹配和@Autowried一樣
-----------------------------------------------------------------------
private MyBeanName myBeanName13;
@Resource
public void setMyBeanName(MyBeanName myBeanName13){
this.mybeanName = myBeanName13;
}
---------------------------------------------------------------------
private MyBeanName myBeanName;
@Resource
public void setMyBeanName33(MyBeanName myBeanName){
this.mybeanName = myBeanName;
}
- 如果以上條件都不滿足,則根據(jù)類型匹配侵续,如果有多個或沒有倔丈,則報(bào)錯。
從JDK9開始状蜗,@Resource
不包含再jdk中需五,使用時需要導(dǎo)入java.xml.ws.annotation
模塊。
- @Inject
和@Autowried
一樣轧坎,該注解可以使用在field宏邮,構(gòu)造器,方法上缸血。
通過類型注入蜜氨。
有一點(diǎn)需要注意,如果你的裝配使用注解裝配捎泻,則會忽略你的xml如何配置的
autowire
屬性飒炎,也就是說無論> 你怎么配置autowire
都不起作用。還有如果你想使用xml的注解自動裝配笆豁,需要添加
<context:annotation-config/>