所谓自动装配,就是将一个Bean注入到其余Bean的Property中,相似于如下:java
<bean id="customer" class="com.lei.common.Customer" autowire="byName" />
Spring支持5种自动装配模式,以下:spring
no ——默认状况下,不自动装配,经过“ref”attribute手动设定。函数
buName ——根据Property的Name自动装配,若是一个bean的name,和另外一个bean中的Property的name相同,则自动装配这个bean到Property中。this
byType ——根据Property的数据类型(Type)自动装配,若是一个bean的数据类型,兼容另外一个bean中Property的数据类型,则自动装配。spa
constructor ——根据构造函数参数的数据类型,进行byType模式的自动装配。code
autodetect ——若是发现默认的构造函数,用constructor模式,不然,用byType模式。blog
下例中演示自动装配开发
Customer.java以下:io
package com.lei.common; public class Customer { private Person person; public Customer(Person person) { this.person = person; } public void setPerson(Person person) { this.person = person; } //... }
Person.java以下:class
package com.lei.common; public class Person { //... }
默认状况下,须要经过'ref’来装配bean,以下:
<bean id="customer" class="com.lei.common.Customer"> <property name="person" ref="person" /> </bean> <bean id="person" class="com.lei.common.Person" />
根据属性Property的名字装配bean,这种状况,Customer设置了autowire="byName",Spring会自动寻找与属性名字“person”相同的bean,找到后,经过调用setPerson(Person person)将其注入属性。
<bean id="customer" class="com.lei.common.Customer" autowire="byName" /> <bean id="person" class="com.lei.common.Person" />
若是根据 Property name找不到对应的bean配置,以下
<bean id="customer" class="com.lei.common.Customer" autowire="byName" /> <bean id="person_another" class="com.lei.common.Person" />
Customer中Property名字是person,可是配置文件中找不到person,只有person_another,这时就会装配失败,运行后,Customer中person=null。
根据属性Property的数据类型自动装配,这种状况,Customer设置了autowire="byType",Spring会总动寻找与属性类型相同的bean,找到后,经过调用setPerson(Person person)将其注入。
<bean id="customer" class="com.lei.common.Customer" autowire="byType" /> <bean id="person" class="com.lei.common.Person" />
若是配置文件中有两个类型相同的bean会怎样呢?以下:
<bean id="customer" class="com.lei.common.Customer" autowire="byType" /> <bean id="person" class="com.lei.common.Person" /> <bean id="person_another" class="com.lei.common.Person" />
一旦配置如上,有两种相同数据类型的bean被配置,将抛出UnsatisfiedDependencyException异常,见如下:
Exception in thread "main" org.springframework.beans.factory.UnsatisfiedDependencyException:
因此,一旦选择了’byType’类型的自动装配,请确认你的配置文件中每一个数据类型定义一个惟一的bean。
这种状况下,Spring会寻找与参数数据类型相同的bean,经过构造函数public Customer(Person person)将其注入。
<bean id="customer" class="com.lei.common.Customer" autowire="constructor" /> <bean id="person" class="com.lei.common.Person" />
这种状况下,Spring会先寻找Customer中是否有默认的构造函数,若是有至关于上边的’constructor’这种状况,用构造函数注入,不然,用’byType’这种方式注入,因此,此例中经过调用public Customer(Person person)将其注入。
<bean id="customer" class="com.lei.common.Customer" autowire="autodetect" /> <bean id="person" class="com.lei.common.Person" />
注意:
项目中autowire结合dependency-check一块儿使用是一种很好的方法,这样可以确保属性老是能够成功注入。
<bean id="customer" class="com.lei.common.Customer" autowire="autodetect" dependency-check="objects" /> <bean id="person" class="com.lei.common.Person" />
最后,我认为,自动装配虽然让开发变得更快速,可是同时却要花更大的力气维护,由于它增长了配置文件的复杂性,你甚至不知道哪个bean会被自动注入到另外一个bean中。我更愿意写配置文件来手工装配。