使用自动装配注入合作者Bean

Spring能自动装配Bean与Bean之间的依赖关系,即无须使用 ref 显式指定依赖Bean。由BeanFactory检查XML配置文件内容,根据某种规则,为主调Bean注入依赖关系。


Spring的自动装配可通过<beans.../>元素的 default-autowire 属性指定,也可通过<bean.../>元素的 autowire 属性指定。自动装配可以指定到单独Bean,也就是说,同一个容器中完全可让某些Bean使用自动装配,而另一些Bean不使用。


自动装配可以减少配置文件的工作量,但降低了依赖关系的透明性和清晰性。


使用autowire 属性配置自动装配,autowire 属性可以接受如下值:

 > no :不使用自动配置。Bean依赖关系必须通过 ref 元素定义。只是默认的配置,在较大的部署环境中不鼓励改变这个配置,显式配置合作者能够得到更清晰的依赖关系。

 > byName:根据属性名自动装配。BeanFactory查找容器中的全部Bean,找出其中id属性与属性同名的Bean来完成注入。如果没有找到匹配的Bean实例,则Spring不会进行任何注入。

 > byType:根据属性类型自动装配。BeanFactory查找容器中的全部Bean,如果正好有一个与依赖属性类型相同的Bean,就自动注入这个属性;如果有多个这样的Bean,就抛出一个异常;如果没有匹配的Bean实例,则什么都不会发生,属性不会被设置。如果需要无法自动装配时抛出异常,则设置dependency-check="objects"。

 > constructor:与byType类似,区别是用于构造注入的参数。如果BeanFactory中不是恰好有一个Bean与构造参数类型相同,则会抛出一个异常。

 > autodetect:BeanFactory根据Bean内部结构,决定使用constructor或byType。如果找到一个默认的构造函数,那么就会应用byType。


byType规则:通过名字注入依赖关系,假如Bean A9的实现类包括setB()方法,而Spring的配置文件恰好包含id 为b的Bean,则Spring容器会将b实例注入Bean A中。如果容器中没有名字匹配的Bean,Spring则不会做任何事情。

package autowire;

public class Man {	
	
	private Dog dog;
	
	public void setGundog(Dog dog){		//byName需要提供的依赖注入的方法,set+Bean名(Bean名首字母大写)
		this.dog = dog;
	}

	public void auto(){
		System.out.println(dog.d());
	}
}
或者

package autowire;

public interface M {
	public void auto();
}

+

package autowire;

public class Man implements M {	
	//使用自动装配注入合作者Bean
	private Dog dog;
	
	public void setGundog(Dog dog){		//byName需要提供的依赖注入的方法,set+Bean名(Bean名首字母大写)
		this.dog = dog;
	}

	public void auto(){
		System.out.println(dog.d());
	}
}

package autowire;

public interface Dog {

	public String d();
}

package autowire;

public class Gundog implements Dog {

	private String name;
	
	public void setName(String name) {
		this.name = name;
	}

	public String d() {
		// TODO Auto-generated method stub
		return name;
	}

}

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xmlns="http://www.springframework.org/schema/beans"
 xsi:schemaLocation="http://www.springframework.org/schema/beans 
 http://www.springframework.org/schema/beans/spring-beans-4.2.xsd"
>
	<!-- 自动装配 	byName没找到匹配的Bean实例不会有注入,byType同样,但有多个这样属性类型的Bean时会抛出异常	-->
	<bean id="man" class="autowire.Man" autowire="byName"/>
	<bean id="gundog" class="autowire.Gundog">
		<property name="name" value="wangwang"/>
	</bean>
	
</beans>

package autowire;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Test {

	public static void main(String[] args) {
		
		ApplicationContext ctx =
				new ClassPathXmlApplicationContext("bean.xml");
		
		Man m = ctx.getBean("man",Man.class);
		//M m = ctx.getBean("man",M.class);
		
		m.auto();
	}
}



byType规则:根据类型匹配来注入依赖关系。假如A实例有setB(B b)方法,而Spring配置文件中恰好有一个类型B的Bean实例,容器为A注入类型匹配的Bean实例;如果容器中没有一个类型为B的实例,则什么都不会发生;但如果容器中有多余一个的B实例,都将会抛出异常。

package autowire;

public class Man implements M {		//可以不使用接口

	private Dog dog;
	
	/*public void setGundog(Dog dog){
		this.dog = dog;
	}*/

	public void setDog(Dog dog) {		//byType需要setter方法的参数类型与容器中Bean的类型相同,
		this.dog = dog;					//在这里setGundog(Dog dog)、setDog(Dog dog)都可完成依赖注入
	}
	
	public void auto(){
		System.out.println(dog.d());
	}
}

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xmlns="http://www.springframework.org/schema/beans"
 xsi:schemaLocation="http://www.springframework.org/schema/beans 
 http://www.springframework.org/schema/beans/spring-beans-4.2.xsd"
>
	<!-- 自动装配 	byName没找到匹配的Bean实例不会有注入,byType同样,但有多个这样属性类型的Bean时会抛出异常	-->
	<bean id="man" class="autowire.Man" autowire="byType"/>
	<bean id="gundog" class="autowire.Gundog">
		<property name="name" value="wangwang"/>
	</bean>
	
</beans>

测试及结果都一样



异常情况:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xmlns="http://www.springframework.org/schema/beans"
 xsi:schemaLocation="http://www.springframework.org/schema/beans 
 http://www.springframework.org/schema/beans/spring-beans-4.2.xsd"
>
	<!-- 自动装配 	byName没找到匹配的Bean实例不会有注入,byType同样,但有多个这样属性类型的Bean时会抛出异常	-->
	<bean id="man" class="autowire.Man" autowire="byType"/>
	<bean id="gundog" class="autowire.Gundog">
		<property name="name" value="wangwang"/>
	</bean>
	<!-- 多于一个同为Dog类型的Bean -->
	<bean id="petdog" class="autowire.Petdog">
		<property name="name" value="ohoh"/>
	</bean>
</beans>


package autowire;

public class Petdog implements Dog {

	private String name;
	
	public void setName(String name) {
		this.name = name;
	}

	@Override
	public String d() {
		// TODO Auto-generated method stub
		return name;
	}

}


结果



即用自动装配依赖,又使用ref显式指定依赖时:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xmlns="http://www.springframework.org/schema/beans"
 xsi:schemaLocation="http://www.springframework.org/schema/beans 
 http://www.springframework.org/schema/beans/spring-beans-4.2.xsd"
>
	<!-- 即用自动装配依赖,又使用ref显式指定依赖时 -->
	<bean id="man" class="autowire.Man" autowire="byName">
		<property name="gundog" ref="petdog"/>
	</bean>
	<bean id="gundog" class="autowire.Gundog">
		<property name="name" value="wangwang"/>
	</bean>
	<!-- 多于一个同为Dog类型的Bean -->
	<bean id="petdog" class="autowire.Petdog">
		<property name="name" value="ohoh"/>
	</bean>
	
</beans>

结果


显式指定的依赖覆盖自动装配

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值