在xml配置文件中,autowire有5種類型,可以在<bean/>元素中使用autowire屬性指定:
模式 說明
no 不使用自動裝配,必須通過ref元素指定依賴,默認設置。
byName 根據屬性名自動裝配。此選項將檢查容器并根據名字查找與
屬性完全一致的bean,并將其與屬性自動裝配。
byType 如果容器中存在一個與指定屬性類型相同的bean,那么將與
該屬性自動裝配;如果存在多個該類型bean,那么拋出異
常,并指出不能使用byType方式進行自動裝配;如果沒有找
到相匹配的bean,則什么事都不發生,也可以通過設置
dependency-check="objects"讓Spring拋出異常。
constructor 與byType方式類似,不同之處在于它應用于構造器參數。如
果容器中沒有找到與構造器參數類型一致的bean,那么拋出
異常。
autodetect 通過bean類的自省機制(introspection)來決定是使用
constructor還是byType方式進行自動裝配。如果發現默認的
構造器,那么將使用byType方式。
可以設置bean使自動裝配失效:
采用xml格式配置bean時,將<bean/>元素的autowire-candidate屬性設置為false,這樣容器在查找自動裝配對象時,將不考慮該bean,即它不會被考慮作為其它bean自動裝配的候選者,但是該bean本身還是可以使用自動裝配來注入其它bean的。
下面用實例來說明:準備3個類
public class Home {
private String addr;
public String getAddr() {
return addr;
}
public void setAddr(String addr) {
this.addr = addr;
}
}
public class Person {
private String name;
private Home myHome;
public Person(Home myHome){
this.myHome = myHome;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Home getMyHome() {
return myHome;
}
public void setMyHome(Home myHome) {
this.myHome = myHome;
}
}
public class Test {
private Date time;
private String str;
public Date getTime() {
return time;
}
public void setTime(Date time) {
this.time = time;
}
public String getStr() {
return str;
}
public void setStr(String str) {
this.str = str;
}
}
一.byName的裝配方式
spring配置文件
<?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.0.xsd">
<bean id="test" class="autowire.Test" autowire="byName">
<property name="str">
<value>ding</value>
</property>
</bean>
<bean id="time" class="java.util.Date"/>
</beans>
測試類:
public class TestMain {
public static void main(String[] args) {
ApplicationContext at = new ClassPathXmlApplicationContext("applicationContext9.xml");
Test t = (Test)at.getBean("test");
/*
代碼若采用了byName的裝配方式,也就是在配置文件中id為test的bean裝入后,因為是byName裝配,同時
Test類中含有time屬性,所以spring會自動查找id為time的bean來設置time的值。
若在配置文件中把autowire="byName"去掉,則time的值為空
*/
System.out.println(t.getStr());
System.out.println(t.getTime());
}
執行這個類可以看到:
ding
Wed Oct 29 09:19:29 CST 2008
證明time已經被注入了
若在配置文件中把autowire="byName"去掉,則可以看到
ding
null
二.byName的裝配方式
代碼都不用改,只需要在spring配置文件里面把 autowire="byName"換成autowire="byType"就可以了
這種裝配方式,則spring會自動查找與Test類中time屬性類型相同的bean,不管這個
bean的id是什么(byName中的id必須與屬性對應,而這里不要求),都可以用來設置time的值,隨便改動
bean的名字都可以,比如<bean id="ti252752" class="java.util.Date"/>的名字都可以,同樣是對的
若存在多個這樣的bean,則會拋出異常。
增加一個bean <bean id="time2" class="java.util.Date"/>
運行可以看到異常:
Exception in thread "main" org.springframework.beans.factory.UnsatisfiedDependencyException:
Error creating bean with name 'test' defined in class path resource [applicationContext9.xml]:
Unsatisfied dependency expressed through bean property 'time': There are 2 beans of type [java.util.Date]
available for autowiring by type: [ti252752, time2]. There should have been exactly 1 to be able to autowire
property 'time' of bean 'test'. Consider using autowiring by name instead.
三.構造方法裝載
spring配置文件
<?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.0.xsd">
<bean id="person" class="autowire.Person" autowire="constructor">
<property name="name">
<value>ding</value>
</property>
</bean>
<bean id="myHome" class="autowire.Home">
<property name="addr">
<value>江西</value>
</property>
</bean>
</beans>
測試類
public class TestMain2 {
public static void main(String[] args) {
ApplicationContext atx = new ClassPathXmlApplicationContext("applicationContext10.xml");
Person p = (Person)atx.getBean("person");
System.out.println(p.getName());
System.out.println(p.getMyHome().getAddr());
/*
* 這段代碼是通過構造方法裝載的,配置文件里面有autowire="constructor",Person類里面
* 的構造方法含有參數myHome,spring會通過這個構造方法來查找與構造方法參數類型相同的bean,
* 把它裝載進來,如果出現兩個類型一樣的bean會拋出異常。
* */
}
}
若將Person類里面 含有參數myHome的構造方法去掉則會報錯
四.不使用自動裝配
<?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.0.xsd">
<bean id="person" class="autowire.Person">
<property name="name">
<value>ding</value>
</property>
<property name="myHome">
<ref local="myHome"/>
</property>
</bean>
<bean id="myHome" class="autowire.Home">
<property name="addr">
<value>江西</value>
</property>
</bean>
</beans>
public class TestMian3 {
public static void main(String[] args) throws Exception {
// 默認的no裝載模式
ApplicationContext atx = new ClassPathXmlApplicationContext(
"applicationContext11.xml");
Person p = (Person) atx.getBean("person");
System.out.println(p.getName());
System.out.println(p.getMyHome().getAddr());
// 若使用這個Person類的構造方法需是默認的,自己寫的要去掉,否則拋出異常。??
}
}
可以看到這里的配置文件里面用
<property name="myHome">
<ref local="myHome"/>
</property>
注入了,否則得不到這個屬性,同時Person類的構造方法需是默認的,其他的要去掉,否則拋出異常。
五.autodetect
通過bean類的自省機制(introspection)來決定是使用constructor還是byType方式進行自動裝配。如果發現默認的構造器,那么將使用byType方式。
這個就不詳細講了。
posted on 2008-10-29 09:44
老丁 閱讀(1526)
評論(0) 編輯 收藏 所屬分類:
spring