09-依赖的自动装配

依赖自动装配(Dependency Autowiring)是 Spring 框架中非常重要的一个特性,它可以在无需显式配置 Bean 之间关系的情况下自动将相互依赖的 Bean 注入到目标对象中,从而简化了配置文件的编写和维护工作。

1、根据属性名称自动装配(byName 自动装配)

原理是通过比较目标 Bean 中各个属性的名称和配置文件中 Bean 的 ID,如果匹配则将对应的 Bean 实例注入到目标属性中。例如:

public class User {
    private Address address;
    
    public void setAddress(Address address) {
        this.address = address;
    }
    
    // ...
}
<bean id="address" class="com.example.Address"/>

<bean id="user" class="com.example.User" autowire="byName">
    <property name="address" value="address"/>
</bean>

在上述示例中,<bean> 元素中的 autowire 属性设置为 byName,表示使用根据属性名称自动装配的方式进行依赖注入。同时,在 property 元素中,name 属性的值与 Bean 的 ID 相同,使得 Spring 可以从容器中查找对应的实例并将其注入到 User 类的 address 属性中。

需要注意的是,当 Bean 中存在多个属性与容器中的 Bean ID 匹配时,Spring 将会注入名称最匹配的 Bean。可以通过在 property 元素中设置 ref 属性来强制指定某个 Bean 实例。例如:

public class User {
    private Address homeAddress;
    private Address workAddress;
    
    public void setHomeAddress(Address homeAddress) {
        this.homeAddress = homeAddress;
    }
    
    public void setWorkAddress(Address workAddress) {
        this.workAddress = workAddress;
    }
    
    // ...
}
<bean id="homeAddress" class="com.example.Address"/>
<bean id="workAddress" class="com.example.Address"/>

<bean id="user" class="com.example.User" autowire="byName">
    <property name="homeAddress" ref="homeAddress"/>
    <property name="workAddress" ref="workAddress"/>
</bean>

在上述示例中,通过在 property 元素中设置 ref 属性显式地指定目标 Bean 应当注入哪个 Bean 实例,避免了自动装配出现歧义的情况。

2、根据类型自动装配(byType 自动装配)

原理是通过比较目标 Bean 中各个属性的类型和配置文件中 Bean 的类型,如果匹配则将对应的 Bean 实例注入到目标属性中。例如:

public class BlogService {
    private BlogDao blogDao;
    
    public void setBlogDao(BlogDao blogDao) {
        this.blogDao = blogDao;
    }
    
    // ...
}

如果在 Spring 的配置文件中只有一个类型为 BlogDao 的 Bean,那么 Spring 就会自动将该 Bean 注入到 BlogService 类的 blogDao 属性中。

<bean id="blogDao" class="com.example.BlogDao"/>
<bean id="blogService" class="com.example.BlogService" autowire="byType"/>

在上述示例中,<bean> 元素中的 autowire 属性设置为 byType,表示使用根据属性类型自动装配的方式进行依赖注入。

需要注意的是,当容器中存在多个类型相同的 Bean 时,Spring 将会抛出异常,因为无法确定应该将哪个 Bean 注入到目标属性中。在这种情况下,可以通过在属性上添加 @Qualifier 注解或者在 <bean> 元素中添加 qualifier 属性来指定具体的 Bean。例如:

public class BlogService {
    @Autowired
    @Qualifier("blogDao1")
    private BlogDao blogDao;
    
    // ...
}
<bean id="blogDao1" class="com.example.BlogDao"/>
<bean id="blogDao2" class="com.example.BlogDao"/>

<bean id="blogService" class="com.example.BlogService" autowire="byType">
    <qualifier value="blogDao1"/>
</bean>

在上述示例中,@Qualifier 注解指定了具体的 Bean 名称,而在 <bean> 元素中的 qualifier 属性也可以达到同样的效果。

3、根据构造方法自动装配(byConstructor 自动装配)

原理是通过比较目标 Bean 在构造方法中的参数类型和配置文件中 Bean 的类型,如果匹配则将对应的 Bean 实例注入到构造方法中。

public class BlogService {
    private BlogDao blogDao;
    
    public BlogService(BlogDao blogDao) {
        this.blogDao = blogDao;
    }
    
    // ...
}

如果在 Spring 的配置文件中只有一个类型为 BlogDao 的 Bean,那么 Spring 就会自动将该 Bean 注入到 BlogService 类的构造方法中。

<bean id="blogDao" class="com.example.BlogDao"/>
<bean id="blogService" class="com.example.BlogService" autowire="constructor"/>

在上述示例中,<bean> 元素中的 autowire 属性设置为 constructor,表示使用根据构造方法自动装配的方式进行依赖注入。

需要注意的是,当容器中存在多个类型相同的 Bean 时,Spring 将会抛出异常,因为无法确定应该将哪个 Bean 注入到构造方法中。在这种情况下,可以通过在构造方法中添加 @Qualifier 注解或者在 <bean> 元素中添加 qualifier 属性来指定具体的 Bean。例如:

public class BlogService {
    private BlogDao blogDao;
    private BlogCommentDao commentDao;
    
    public BlogService(BlogDao blogDao, @Qualifier("commentDao1") BlogCommentDao commentDao) {
        this.blogDao = blogDao;
        this.commentDao = commentDao;
    }
    
    // ...
}
<bean id="blogDao" class="com.example.BlogDao"/>
<bean id="commentDao1" class="com.example.BlogCommentDao"/>
<bean id="commentDao2" class="com.example.BlogCommentDao"/>

<bean id="blogService" class="com.example.BlogService" autowire="constructor">
    <constructor-arg ref="blogDao"/>
    <constructor-arg name="commentDao" ref="commentDao1"/>
</bean>

在上述示例中,@Qualifier 注解指定了具体的 Bean 名称,而在 <bean> 元素中的 constructor-arg 元素的 name 属性也可以达到同样的效果。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值