spring自動注入
一般的方式需要配置bean或ref引用bean,自動注入會自動進行匹配,如果存在則建立。
匹配原則:使用Bean的id屬性中的值去和相對應的值匹配
關鍵詞autowire=""
default:預設
byType:根據型別自動匹配
byName:根據名字自動匹配
constructor: 根據構造器匹配
根據型別匹配
比如在person中使用byType並注入了Wife的bean標籤:
在Person類中是有Wife這個型別的屬性:
已知ioc容器中的存在Wife型別的bean,那麼就會自動將Wife這個bean注入到Persong的屬性中
測試方法:
/**
* 自動注入
*/
@Test
public void fun5(){
System.out.println("begin!");
Person person = app.getBean("person", Person.class);
System.out.println(person);
}
輸出結果:
Wife載入 begin! Person{id=null, name='null', gender='null', birth=null, ls=null, course=null, wife=Wife{id=null, name='妻子', gender='null', birth=null, ls=null, course=null}}
從結果可以發現注入Person中的Wife型別的bean就是我們配置的Wife型別的bean。
但是使用這個方式有一個問題:
當我們建立兩個相同Wife型別的bean時就會 報錯。
根據名字匹配
此時我將byType改為byName,然後注入兩個Wife型別的bean -- wife 和 wife1:
那麼這個時候就會自動去匹配Person類中set()方法的值與哪一個Wife型別Bean的id相同,
可以發現Person中setWife()方法與id="wife"的匹配,而不是與id="wife1"匹配,所以會將id="wife"的bean注入Person的wife屬性中。
執行上面的測試程式碼:
Wife載入
Wife載入
begin!
Person{id=null, name='null', gender='null', birth=null, ls=null, course=null, wife=Wife{id=null, name='前妻', gender='null', birth=null, ls=null, course=null}}
結果也確實是與set()方法匹配的那個Wife型別的Bean被注入。
這裡載入兩次是因為配置了兩個不同的Wife型別的Bean。
如果將set()方法改為:
檢視結果:
begin!
Person{id=null, name='null', gender='null', birth=null, ls=null, course=null, wife=Wife{id=null, name='妻子', gender='null', birth=null, ls=null, course=null}}
被注入的是與wife1匹配的bean。
根據構造器匹配
此時進行匹配需要建構函式中的引數只有ioc容器中注入的引數,例如ioc容器中只注入了Wife的Bean,那麼建構函式只能有Wife型別的引數,如果有其它引數那麼將無法匹配。
此時將Person類中加入一個只有Wife引數的建構函式
這個方式會優先根據名字進行匹配:
比如下面:
引數為wife時輸出結果:
引數為wife1時輸出結果:
這和我們的配置的是一樣的:
如果名字沒有找到,那麼就會根據型別進行匹配:
前面已知根據型別匹配只能注入一個Wife型別的bean,這裡如果存在多個相同的Bean,那麼會注入失敗但是不會報錯:
在xml中並沒有配置wife2這個bean:
此時的輸出結果為:
結果注入的是id="wife"的bean。
如果在自動注入的時候有兩個相同的Bean參與匹配,那麼可以使用primary="true",表示該Bean為主要Bean,如果primary="false",表示不參與自動注入。
輸出結果:
存在相同的Bean也可以注入,並且為設定了優先的Bean,前面的byType也可以通過這個方式進行配置。