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

来源:互联网 发布:服务器端口检测工具 编辑:程序博客网 时间:2024/05/22 11:44

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 {//使用自动装配注入合作者Beanprivate 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 stubreturn 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;}@Overridepublic String d() {// TODO Auto-generated method stubreturn 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>

结果


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

原创粉丝点击