Spring 中的自动装配

时间:2022-07-23
本文章向大家介绍Spring 中的自动装配,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

目录

  • 1. 前言
    • 1.1 Spring 的装配机制
    • 1.2 自动配置的两种方式
  • 2. 利用注解实现自动配置
    • 2.1 @Autowired
    • 2.2 @Qualifier
    • 2.3 @Resource
  • 3. 总结

1. 前言

1.1 Spring 的装配机制

自动装配指使用 Spring 满足 Bean 依赖的一种方法,Spring 会在应用上下文中为某个 Bean 寻找其依赖的 Bean,主要有三种装配机制:

  1. XML 中显式配置;
  2. Java 中显式配置;
  3. 隐式的 Bean 发现机制和自动装配;

而 Spring 的自动装配主要从两方面来实现:

  1. 组件扫描:Component Scanning,Spring 自动发现应用上下文中所创建的 Bean。
  2. 自动装配:Autowiring,Spring 自动满足不同 Bean 之间的依赖,即 IoC/DI.

1.2 自动配置的两种方式

  • byName
<bean id="user" class="com.cunyu.pojo.User" autowire="byName">
   <property name="name" value="村雨遥"/>
</bean>

按名称自动装配,在配置 Bean 时,加入一个 autowire 属性值 byName。此时,Spring 将先去查找类中所有的 Setter 方法,然后去 Spring 容器中寻找是否有该字符串名称 id 的对象相匹配,如果找到了,就取出注入;若是没有找到,那么就报空指针异常。

  • byType

按类型自动装配,在配置 Bean 时,加入一个 autowire 属性值 byType。此时需要有一个 前提条件:同一类型的对象,在 Spring 容器中有且只有一个,否则就会报错。此时,Spring 将去查找类中所有的 Setter 方法,然后在 Spring 容器查找是否有该字符串名称 id 的对象,找到匹配的对象就取出注入,否则就抛出空指针异常。

2. 利用注解实现自动配置

2.1 @Autowired

@Autowired 按照类型(byType)自动配置,不支持 id 匹配。

  1. 去掉 set 方法,利用 @Autowired 进行注解;
public class User{
    @Autowired
    private Address address;

    public Address getAddress(){
        return address;
    }
}
  1. 配置 Spring 配置文件;
<context:annotation-config/>

<bean id="addr" class="com.cunyu.pojo.Address"/>
<bean id="user" class="com.cunyu.pojo.User"/>

2.2 @Qualifier

@Qualifier 不能单独使用,需要配合 @Autowired 使用,从而实现按名称(byName)自动配置。

  1. 在属性中添加 @Qualifier
public class User{
    @Autowired
    @Qualifier(value="addr2")
    private Address address;

    public Address getAddress(){
        return address;
    }
}
  1. 配置 Spring 配置文件;
<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"/>

2.3 @Resource

@Resource 默认按照名称 byName 的方式进行装配,但如果有指定的 name 属性,则 优先 按照指定属性进行 byName 的方式查找并装配。

  • 优先 byName
  1. 属性配置 @Resource
public class User{
    // 指定 name 属性,先按照该属性进行按名称自动装配
    @Resource(name = "addr2")
    private Address address;
}
  1. 配置 Spring 配置文件
<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
  1. 属性配置 @Resource
public class User{
    // 先 byName 查找失败,然后 byType 查找成功
    @Resource
    private Address address;
}
  1. 配置 Spring 配置文件
<context:annotation-config/>

<bean id="addr" class="com.cunyu.pojo.Address"/>
<bean id="user" class="com.cunyu.pojo.User"/>

3. 总结

@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