Spring 容器可以在不使用< constructor-arg >和< property > 元素的情况下自动装配、相互协作bean 之间的关系。使用< bean >元素的 autowire 属性为一个 bean 定义指定自动装配模式有以下几种方式:
1、no
默认设置,没有自动装配.
2、byName
通过属性名进行自动装配。
将它的属性与在配置文件中被定义为相同名称的 beans 的属性进行连接。
applicationContext.xml中的配置:
<!--将Dept对象装配到Spring IOC容器中-->
<bean id="dept" class="com.zm.bean.autowired.Dept">
<property name="deptId" value="1"/>
<property name="deptName" value="市场部"/>
</bean>
<bean class="com.zm.bean.autowired.Employee" id="emp" autowire="byName"></bean>
测试方法:
@Test
public void test01(){
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext-autowired.xml");
Employee emp = context.getBean("emp", Employee.class);
System.out.println(emp);
}
运行结果:
Dept的属性dept会自动找到id/name为dept的bean,如果没有定义为dept的bean则装配失败。
3、byType
由属性的数据类型进行自动装配。
applicationContext.xml中的配置:
<bean id="dept" class="com.zm.bean.autowired.Dept">
<property name="deptId" value="1"/>
<property name="deptName" value="市场部"/>
</bean>
<!--将Dept通过属性的数据类型进行装配
缺点:如果存在多个相同类型的对象,则会报错
-->
<bean class="com.zm.bean.autowired.Employee" id="emp" autowire="byType"></bean>
测试方法与byName的相同。
运行结果:
找不到与属性名相同的bean也能装配成功,因为是根据属性类型查找的,但是当出现多个同一属性的bean时会报异常。
4、constructor
与byType类似,通过构造函数建立联系。
实体类中必须有带有bean对象的构造方法。
// 带有bean类型的构造函数
public Employee(Dept dept) {
this.dept = dept;
}
applicationContext.xml文件中的配置:
<bean id="dept" class="com.zm.bean.autowired.Dept">
<property name="deptId" value="1"/>
<property name="deptName" value="市场部"/>
</bean>
<!--通过构造方法进行自动装配。需要注意的是-->
<bean id="emp" class="com.zm.bean.autowired.Employee" autowire="constructor"></bean>
测试方法与byName的相同。
运行结果:
constructor自动装配具有和byType自动装配相同的局限性。当发现多个Bean匹配某个构造器的入参时,Spring不会尝试去考虑哪一个Bean更适合自动装配,会装配失败;如果一个类有多个构造器,它们都满足自动装配的条件时,Spring也不会尝试去考虑哪一个构造器更加适合。
5、autodetect
由spring 来决定使用哪一种类型的自动装配。一般,Spring会先尝试通过 constructor 使用自动装配来连接,如果它不执行,尝试通过 byType 来自动装配。