自动装配指使用 Spring 满足 Bean 依赖的一种方法,Spring 会在应用上下文中为某个 Bean 寻找其依赖的 Bean,主要有三种装配机制:
而 Spring 的自动装配主要从两方面来实现:
<bean id="user" class="com.cunyu.pojo.User" autowire="byName">
<property name="name" value="村雨遥"/>
</bean>
按名称自动装配,在配置 Bean 时,加入一个 autowire
属性值 byName
。此时,Spring 将先去查找类中所有的 Setter
方法,然后去 Spring 容器中寻找是否有该字符串名称 id
的对象相匹配,如果找到了,就取出注入;若是没有找到,那么就报空指针异常。
按类型自动装配,在配置 Bean 时,加入一个 autowire
属性值 byType
。此时需要有一个 前提条件:同一类型的对象,在 Spring 容器中有且只有一个,否则就会报错。此时,Spring 将去查找类中所有的 Setter
方法,然后在 Spring 容器查找是否有该字符串名称 id
的对象,找到匹配的对象就取出注入,否则就抛出空指针异常。
@Autowired
按照类型(byType
)自动配置,不支持 id
匹配。
set
方法,利用 @Autowired
进行注解;public class User{
@Autowired
private Address address;
public Address getAddress(){
return address;
}
}
<context:annotation-config/>
<bean id="addr" class="com.cunyu.pojo.Address"/>
<bean id="user" class="com.cunyu.pojo.User"/>
@Qualifier
不能单独使用,需要配合 @Autowired
使用,从而实现按名称(byName
)自动配置。
@Qualifier
public class User{
@Autowired
@Qualifier(value="addr2")
private Address address;
public Address getAddress(){
return address;
}
}
<context:annotation-config/>
<bean id="addr" class="com.cunyu.pojo.Address"/>
<bean id="addr2" class="com.cunyu.pojo.Address"/>
<bean id="user" class="com.cunyu.pojo.User"/>
@Resource
默认按照名称 byName
的方式进行装配,但如果有指定的 name
属性,则 优先 按照指定属性进行 byName
的方式查找并装配。
byName
@Resource
public class User{
// 指定 name 属性,先按照该属性进行按名称自动装配
@Resource(name = "addr2")
private Address address;
}
<context:annotation-config/>
<bean id="addr" class="com.cunyu.pojo.Address"/>
<bean id="addr2" class="com.cunyu.pojo.Address"/>
<bean id="user" class="com.cunyu.pojo.User"/>
byType
@Resource
public class User{
// 先 byName 查找失败,然后 byType 查找成功
@Resource
private Address address;
}
<context:annotation-config/>
<bean id="addr" class="com.cunyu.pojo.Address"/>
<bean id="user" class="com.cunyu.pojo.User"/>
@Autowired
和 @Resource
两者的作用相同,都是利用注解方式注入对象,均支持装配 Bean,都可以写在字段上,或者写在 setter
方法上。
@Autowired
属于 Spring 规范,默认按类型(byType
)装配,默认情况下要求依赖对象必须存在。若要允许 null
,则可设置其 required = false
,若想要按名称(byName
)装配,则可以搭配 @Qualifier
共同使用。
@Resource
属于 J2EE 规范,默认按名称(byName
)装配,名称可以通过 name
属性来指定。如果没有 name
属性,则当该注解写在 字段 上时,默认 取字段名 进行按名称(byName
)查找,如果注解写在 setter 方法 上,则默认取 属性名 进行装配。当找不到与名称匹配的 Bean 时才按类型(byType
)装配。但是需要注意的是,如果 name
属性一旦指定,就只会按照名称进行装配。
两者执行顺序不同,@Autowired
优先 byType
,若要实现 byName
,需要搭配 @Qualifier
,而 @Resource
优先 byName
,找不到匹配的 Bean 时,再 byType
。