1 配置文件的方法
咱們編寫spring框架的代碼時候。一直遵循是這樣一個規則:全部在spring中注入的bean都建議定義成私有的域變量。而且要配套寫上get和set方法。
Boss擁有Office和Car類型的兩個屬性:java
1
2
3
4
5
6
7
8
9
10
11
|
public class Boss
{
private Car car;
private Office office;
//省略 get/setter
@Override
public String toString()
{
return "car:" + car + "/n" + "office:" + office;
}
}
|
咱們在Spring容器中將Office和Car聲明爲Bean,並注入到Boss Bean中,下面是使用傳統XML完成這個工做的配置文件beans.xml: spring
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
<?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.5.xsd">
<bean id="boss" class="Boss">
<property name="car" ref="car"/>
<property name="office" ref="office" />
</bean>
<bean id="office" class="Office">
<property name="officeNo" value="002"/>
</bean>
<bean id="car" class="Car" scope="singleton">
<property name="brand" value="紅旗CA72"/>
<property name="price" value="2000"/>
</bean>
</beans>
|
當咱們運行如下代碼時,控制檯將正確打出boss的信息:app
1
2
3
4
5
6
7
8
9
10
11
12
13
|
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test
{
public static void main(String[] args)
{
String[] locations = {"beans.xml"};
ApplicationContext ctx = new ClassPathXmlApplicationContext(locations);
Boss boss = (Boss) ctx.getBean("boss");
System.out.println(boss);
}
}
|
2 @Autowired的使用
Spring 2.5引入了@Autowired註釋,它能夠對類成員變量、方法及構造函數進行標註,完成自動裝配的工做。經過@Autowired的使用來消除set,get方法。
下面是@Autowired的定義:框架
1
2
3
4
5
6
7
8
|
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.CONSTRUCTOR, ElementType.FIELD, ElementType.METHOD})
public @interface Autowired
{
//是否必須知足依賴性檢查,默認時,凡是應用了@Autowired註解的屬性和方法都必須找到合適的協做者,不然Spring容器會拋出異常,
//經過調整required屬性取值可以改變這一行爲。
boolean required() default true;
}
|
注意:@Autowired註解可以做用於構建器、屬性、方法。這裏的方法不侷限於設值方法,即setter方法,常見的各類方法均可以應用這一註解。
要使用@Autowired實現咱們要精簡程序的目的,須要這樣來處理:
在applicationContext.xml中加入:
<!-- 該 BeanPostProcessor 將自動對標註 @Autowired 的 Bean 進行注入 -->
<bean class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor"/>
Spring經過一個BeanPostProcessor對@Autowired進行解析,因此要讓@Autowired起做用必須事先在Spring容器中聲明AutowiredAnnotationBeanPostProcessor Bean。
修改在原來注入Spirng容器中的bean的方法,在域變量上加上標籤@Autowired,而且去掉相應的get和set方法。
使用 @Autowired 註釋的 Boss.javaide
1
2
3
4
5
6
7
8
|
import org.springframework.beans.factory.annotation.Autowired;
public class Boss
{
@Autowired
private Car car;
@Autowired
private Office office;
}
|
在applicatonContext.xml中把原來引用的<porpery>標籤也去掉。函數
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
<?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.5.xsd">
<!-- 該 BeanPostProcessor 將自動起做用,對標註 @Autowired 的 Bean 進行自動注入 -->
<bean class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor"/>
<!-- 移除 boss Bean 的屬性注入配置的信息 -->
<bean id="boss" class="Boss"/>
<bean id="office" class="Office">
<property name="officeNo" value="001"/>
</bean>
<bean id="car" class="Car" scope="singleton">
<property name="brand" value="紅旗 CA72"/>
<property name="price" value="2000"/>
</bean>
</beans>
|
這樣,當 Spring容器啓動時,AutowiredAnnotationBeanPostProcessor將掃描Spring容器中全部Bean,當發現Bean中擁有@Autowired 註釋時就找到和其匹配(默認按類型匹配)的Bean,並注入到對應的地方中去。 ui
3 @Autowired注入規則
@Autowired默認是按照byType進行注入的,可是當byType方式找到了多個符合的bean,又是怎麼處理的?Autowired默認先按byType,若是發現找到多個bean,則又按照byName方式比對,若是還有多個,則報出異常。
例子:
@Autowired
private Car redCar;
1. spring先找類型爲Car的bean
2. 若是存在且惟一,則OK;
3. 若是不惟一,在結果集裏,尋找name爲redCar的bean。由於bean的name有惟一性,因此,到這裏應該能肯定是否存在知足要求的bean了
@Autowired也能夠手動指定按照byName方式注入,使用@Qualifier標籤,例如:
@Autowired()
@Qualifier("baseDao" )
由於bean的name具備惟一性,理論上是byName會快一點,但spring默認使用byType的方式注入。另外補充一點:@Resource(這個註解屬於J2EE的)的標籤,默認是按照byName方式注入的。spa