自动装配Bean属性
3种类型的自动装配
Spring提供几种技巧用于减少XML的配置数量:
自动装配(autowiring)有助于减少甚至消除配置<property>元素和<constructor-arg>元素,让Spring自动识别如何装配Bean的依赖关系。
自动检测(autodiscovery)比自动装配更进一步,让Spring能自动识别哪些类需要被自动装配成Spring Bean,从而减少<Bean>元素的使用。
Spring的三种自动装配策略:
byName:把与Bean属性具有相同名字或者ID的其他Bean自动装配到对应的属性中,如果没有,该属性不被装配。
- 通过设置autowire属性为byName,为属性自动装配ID与该属性名字相同的Bean。
byType:把与Bean的属性具有相同类型的其他Bean自动装配的Bean对应的属性当中去,若没有,该属性不被装配。
通过设置autowire属性为byType,为属性自动装配类型与该属性类型相同的Bean。
限制:应用只允许存在一个Bean与自动装配的的属性类型相匹配。
使用<bean>元素的primary属性属性为自动装配标识一个首选Bean;为了使用primary属性,要将所有非首选Bean的primary属性设置为false。
通过设置<bean>元素的autowire-candidate属性为false,可以在自动装配时排除某些Bean。
constructor:把与Bean的构造器入参具有相同类型的其他Bean自动装配到Bean构造器的对应入参中。
通过设置autowire属性为constructor,在构造器注入配置Bean时,可以移除<constructor-arg>元素,由Spring在应用上下文自动选择Bean注入到构造器入参中。
和byType自动装配有相同的限制,应用只允许存在一个Bean与自动装配的的属性类型相匹配。
默认自动装配
如果需要为Spring应用上下文中的多数Bean配置相同的autowire属性,可以让Spring为它所创建的所有Bean应用相同的自动装配策略来简化配置。
在配置文件的根元素<beans>上增加default-autowire属性,可以将default-autowire属性设置为任意一种有效的自动装配策略,将其应用与Spring配置文件中的所有Bean。
可以在一个Spring应用上下文中定义多个配置文件,每个配置文件都可以有自己默认的自动装配策略。
<bean>元素的autowire属性可以覆盖<benas>所配置的默认自动装配策略。
混合使用自动装配和自动装配
对某个Bean设置了自动装配策略后,仍然可以为任意一个属性配置<property>元素进行显示装配。
混合使用自动装配和自动装配,可以解决使用byType自动装配策略可能产生的装配不确定性问题。
使用示例
先给出一个导弹接口(IMissile),接口中只有一个发射的方法
package com.li.autowire;
/*导弹接口*/
public interface IMissile {
void fire();
}
在给出一个导弹类,该类实现了导弹接口
package com.li.autowire;
/*导弹类,实现导弹接口*/
public class Missile implements IMissile {
@Override
public void fire() {
System.out.println("The missile is fired...");
}
}
随后是一个无人机类,无人机可以装载导弹,我们直接在该类中进行测试
package com.li.autowire;
import java.io.File;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/*无人机类*/
public class Uav {
/*无人机装配有导弹*/
private IMissile missile;
public IMissile getMissile() {
return missile;
}
public void setMissile(IMissile missile) {
this.missile = missile;
}
public Uav(IMissile missile) {
super();
this.missile = missile;
}
public Uav() {
super();
}
public void attack() {
missile.fire();
}
public static void main(String[] args) {
ApplicationContext ctx=new ClassPathXmlApplicationContext("com"+File.separator+"li"+File.separator+"autowire"+File.separator+"uav.xml");
Uav uav1=(Uav)ctx.getBean("uav");
uav1.attack();
Uav uav2=(Uav)ctx.getBean("uav1");
uav2.attack();
}
}
Spring XML配置文件(不使用自动装配)
<?xml version="1.0" encoding="UTF-8"?>
<!-- 引用Spring的多个Schema空间的格式定义文件 -->
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="missile" class="com.li.autowire.Missile"></bean>
<bean id="uav" class="com.li.autowire.Uav">
<property name="missile" ref="missile"></property>
</bean>
<!-- 对同一个类配置不同的Bean -->
<bean id="uav1" class="com.li.autowire.Uav">
<constructor-arg ref="missile"></constructor-arg>
</bean>
</beans>
Spring XML配置文件(使用自动装配)
<?xml version="1.0" encoding="UTF-8"?>
<!-- 引用Spring的多个Schema空间的格式定义文件 -->
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="missile" class="com.li.autowire.Missile"></bean>
<bean id="uav" class="com.li.autowire.Uav" autowire="byName">
</bean>
<!-- 对同一个类配置不同的Bean -->
<bean id="uav1" class="com.li.autowire.Uav" autowire="constructor">
</bean>
</beans>