在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
老丁 阅读(1518)
评论(0) 编辑 收藏 所属分类:
spring