首先我们来看一下以前我们是如何手动装配一个bean的:
先看一段java程序:
- public class Customer
- {
- private Person person;
- public void setPerson(Person person) {
- this.person = person;
- }
- }
- public class Person {……}
这时在配置文件当中默认autowire属性值为:no,即不使用默认装配,这时只有通过<ref>标签手动装配bean
- <bean id="customer" class="cn.lovepi.***.Customer">
- <property name="person" ref="person" />
- </bean>
- <bean id="person" class="cn.lovepi.***.Person" />
可以看到:person id的名字和customer bean的person属性的名字是一样的。
具体Spring属性注入请看:Spring学习(十七)Spring 参数注入方式介绍
其实,当Spring装配Bean的属性时,如果非常明确,则可以使用自动装配模式。
Spring提供了4种各具特色的自动装配策略:
- byName:把与bean的属性具有相同名字或者id的其他的bean自动装配到bean对应的属性当中。如果没有跟属性名字相匹配的bean,则该属性不进行装配。
- byType:把与bean的属性具有相同类型的其他bean自动装配到bean的对应属性当中。如果没有跟属性类型的bean,则属性不被装配。
- constructor:把与bean的构造函数入参具有相同类型的其他bean自动装配到bean的构造器对应的入参当中。
- autodetect:首先先将尝试使用constructor进行自动装配,如果失败,则尝试使用byType进行自动装配。
接下来详细的了解下这四种装配方式的优缺点。
1.byName:为属性自动装配与该属性名字相同的bean
在Spring当中,所有的东西都会被赋予一个名字。因此,bean的属性也会有一个名字。就像装配进属性的bean一样,假如属性的名字恰好与该属性的bean的名字一样,那么只要配置了autowire属性,Spring便会自动将这个bean装配到属性当中去。
如下所示:
- <bean id="customer" class="cn.lovepi.***.Customer” autowire="byName" />
- <bean id="person" class="cn.lovepi.***.Person" />
2.byType:为属性自动装配与该属性类型相同的bean
- <bean id="customer" class="cn.lovepi.***.Customer” autowire="byType" />
- <bean id="person" class="cn.lovepi.***.Person" />
当存在多个bean的类型与所要装配的属性类型相同的时候,Spring会抛出异常。
为了避免使用byType自动装配而带来的歧义,Spring为我们提供了两种解决方法:
- 可以为自动装配标志一个首选bean,使用primary属性,属性的默认值为true即所有的bean都是首选bean
- 可以取消某个bean自动装配的资格,使用autowire-candidate属性,为false时取消自动装配资格
3.constructor:通过构造器注入来配置bean,取消constructor-arg属性,使用autowire属性设置
- <bean id="customer" class="com.jike.***.Customer” autowire=“constructor" />
- <bean id="person" class="com.jike.***.Person" />
采用constructor构造器注入bean也具有一定的局限性:
当发现多个bean匹配某个构造器入参的时候,Spring不会去猜测哪一个bean更适合装配。此外,如果一个类有多个构造器,那么他们都满足自动装配的条件的时候,Spring也不会尝试去猜测哪一个构造器更适合使用。
4.autodetect:最佳自动装配策略
- <bean id="customer" class="com.jike.***.Customer” autowire=“autodetect" />
- <bean id="person" class="com.jike.***.Person" />
首先先将尝试使用constructor进行自动装配,如果失败,则尝试使用byType进行自动装配。
当Spring要为它所创建的所有Bean应用相同的自动装配策略来简化配置时,可以在根元素<bean>上增加一个default-autowire属性:
- <beans
- xmlns="http://www.springframework.org/schema/beans"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://www.springframework.org/schema/beans
- http://www.springframework.org/schema/beans/spring-beans-3.0.xsd”
- default-autowire=“byType” >
- …………………
- </beans>
- <bean id="customer" class="com.jike.***.Customer“autowire=“byType" >
- <property name="person" ref="person1" />
- </bean>
- <bean id="person" class="com.jike.***.Person" />
- <bean id="person1" class="com.jike.***.Person" />