Spring學(xué)習(xí)手冊(cè)(6)—— bean生命周期管理我們學(xué)習(xí)了如何在IOC容器完成bean構(gòu)造或銷毀時(shí)添加指定操作動(dòng)作。本篇我們將學(xué)習(xí)IOC容器的自動(dòng)注入知識(shí),通過自動(dòng)注入可以極大的減少XML配置工作。
一、自動(dòng)注入
Spring的IOC容器可以自動(dòng)關(guān)聯(lián)bean之間的依賴,我們將其稱為自動(dòng)注入。自動(dòng)注入有以下優(yōu)勢(shì):
- 自動(dòng)注入可有效的減少構(gòu)造器和屬性參數(shù)設(shè)置;
- 自動(dòng)注入可以根據(jù)對(duì)象的變化更改配置。如,需要向類添加依賴關(guān)系,可自動(dòng)滿足該依賴關(guān)系,而無需更改配置信息。
自動(dòng)注入無法注入簡(jiǎn)單屬性,如:基本類型(int、char、boolean等)、String類型和Class。
Spring為我們提供了以下四種自動(dòng)注入方式:
| 模式 | 描述 |
|---|---|
| no | (默認(rèn))不進(jìn)行自動(dòng)注入,必須手動(dòng)配置 |
| byName | 依靠屬性名稱進(jìn)行自動(dòng)注入 |
| byType | 按照屬性類型進(jìn)行自動(dòng)注入,如果有兩個(gè)一樣的類型則拋出異常若不存在該類型則屬性不進(jìn)行注入 |
| constructor | 與byType相似,若不存在構(gòu)造器參數(shù)類型,將產(chǎn)生錯(cuò)誤 |
Tip: 當(dāng)使用byType時(shí),若該屬性類型在IOC容器中存在兩個(gè)或兩個(gè)以上的bean時(shí),此時(shí)為了避免不可預(yù)測(cè)的情況的產(chǎn)生,Spring會(huì)拋出異常。
二、自動(dòng)注入配置
2.1 自動(dòng)注入開關(guān)
當(dāng)我們想要某bean支持自動(dòng)注入時(shí),需要使用<bean>標(biāo)簽中的autowire屬性,而值設(shè)為上表中的某項(xiàng),默認(rèn)為no。樣式如下:
<bean id="autoWrieExample" class="com.example.AutoWireExample" autowire="byName"/>
public class AutoWireExample{
}
2.2全局配置
雖然只需要增加autowire屬性就可以免去為每個(gè)構(gòu)造器參數(shù)或?qū)傩栽O(shè)置配置XML屬性,但是若為每個(gè)bean增加該屬性,也是一個(gè)不小的工作量。幸好,Spring為我們提供了全局的配置方式:default-autowire。樣式如下:
<beans default-autowire="byName">
......
</beans>
同樣,當(dāng)前<bean>設(shè)置的自動(dòng)注入值會(huì)覆蓋全局設(shè)置的值。
Tip:一般情況下,我們多使用byName的方式來進(jìn)行自動(dòng)注入以避免出現(xiàn)按照類型自動(dòng)注入可能導(dǎo)致的異常情況。
三、示例
該示例我們使用byName的自動(dòng)注入方式,使用全局配置的方式使得IOC容器自動(dòng)注入依賴關(guān)系。
public class Address {
private String street;
private String city;
public void setStreet(String street) {
this.street = street;
}
public void setCity(String city) {
this.city = city;
}
@Override
public String toString(){
return "Street: "+ street+" City: "+city;
}
}
public class Person {
private int age;
private String name;
private Address address;
public void setAge(int age) {
this.age = age;
}
public void setName(String name) {
this.name = name;
}
public void setAddress(Address address) {
this.address = address;
}
@Override
public String toString(){
return "age: "+ age+" name: "+name+" address: "+address;
}
}
配置文件如下:
<?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-4.3.xsd"
default-autowire="byType">
<bean id="address" class="com.liangwei.learnspring.Address">
<property name="street" value="NanJingRoad"/>
<property name="city" value="HangZhou"/>
</bean>
<bean id="person" class="com.liangwei.learnspring.Person" autowire="">
<property name="age" value="20"/>
<property name="name" value="Tom"/>
</bean>
</beans>
如上配置文件,我們可以看到id設(shè)置為person的bean并沒有顯示注入屬性address的依賴關(guān)系,我們?cè)赽eans標(biāo)簽里面設(shè)置了default-autowire。同樣我們也注意到,雖然我們開啟了自動(dòng)注入,但是關(guān)于age、name等簡(jiǎn)單類型屬性我們依然需要配置注入關(guān)系。
public class Application {
public static void main(String[] args){
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("bean.xml");
Person person = applicationContext.getBean("person",Person.class);
System.out.println(person.toString());
}
}
運(yùn)行上述代碼,控制臺(tái)得到如下輸出信息:
age: 20 name: Tom address: Street: NanJingRoad City: HangZhou
從輸出信息上我們可以看出,IOC容器自動(dòng)將對(duì)address的依賴注入到了person內(nèi)。
四、總結(jié)
本文我們一起學(xué)習(xí)了自動(dòng)注入相關(guān)的知識(shí),知識(shí)點(diǎn)相對(duì)簡(jiǎn)單,可以在本文給出的源代碼的基礎(chǔ)上使用不同的自動(dòng)注入方式來體會(huì)其中的不同。另外,在平時(shí)的應(yīng)用中一般使用byName方式較多。
本文源代碼下載