@Autowired 凝视遇到的问题,@Qualifier 帮助解决这个问题

当候选 Bean 数目不为 1 时的应对方法

在默认情况下使用 @Autowired 凝视进行自己主动注入时,Spring 容器中匹配的候选 Bean 数目必须有且仅有一个。

当找不到一个匹配的 Bean 时,Spring 容器将抛出BeanCreationException 异常。并指出必须至少拥有一个匹配的
Bean。我们能够来做一个实验:

清单 10. 候选 Bean 数目为 0 时

<?xml version="1.0" encoding="UTF-8" ?

>
<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-2.5.xsd ">

    <bean class="org.springframework.beans.factory.annotation.
        AutowiredAnnotationBeanPostProcessor"/> 

    <bean id="boss" class="com.baobaotao.Boss"/>

    <!-- 将 office Bean 凝视掉 -->
    <!-- <bean id="office" class="com.baobaotao.Office">
    <property name="officeNo" value="001"/>
    </bean>-->

    <bean id="car" class="com.baobaotao.Car" scope="singleton">
        <property name="brand" value=" 红旗 CA72"/>
        <property name="price" value="2000"/>
    </bean>
</beans>

因为 office Bean 被凝视掉了,所以 Spring 容器中将没有类型为Office 的 Bean 了,而 Boss 的office 属性标注了@Autowired。当启动
Spring 容器时。异常就产生了。

当不能确定 Spring 容器中一定拥有某个类的 Bean 时,能够在须要自己主动注入该类 Bean 的地方能够使用@Autowired(required = false),这等于告诉 Spring:在找不到匹配 Bean 时也不报错。来看一下详细的样例:

清单 11. 使用 @Autowired(required = false)

package com.baobaotao;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Required;

public class Boss {

    private Car car;
    private Office office;

    @Autowired
    public void setCar(Car car) {
        this.car = car;
    }
    @Autowired(required = false)
    public void setOffice(Office office) {
        this.office = office;
    }
    …
}

当然,普通情况下,使用 @Autowired 的地方都是须要注入 Bean 的。使用了自己主动注入而又同意不注入的情况一般仅会在开发期或測试期碰到(如为了高速启动 Spring 容器,仅引入一些模块的 Spring 配置文件)。所以@Autowired(required
= false)
 会非常少用到。

和找不到一个类型匹配 Bean 相反的一个错误是:假设 Spring 容器中拥有多个候选 Bean,Spring 容器在启动时也会抛出 BeanCreationException 异常。来看以下的样例:

清单 12. 在 beans.xml 中配置两个 Office 类型的 Bean

…
<bean id="office" class="com.baobaotao.Office">
    <property name="officeNo" value="001"/>
</bean>
<bean id="office2" class="com.baobaotao.Office">
    <property name="officeNo" value="001"/>
</bean>
…

我们在 Spring 容器中配置了两个类型为 Office 类型的 Bean。当对 Boss 的office 成员变量进行自己主动注入时,Spring 容器将无法确定究竟要用哪一个 Bean,因此异常发生了。

Spring 同意我们通过 @Qualifier 凝视指定注入 Bean 的名称,这样歧义就消除了,能够通过以下的方法解决异常:

清单 13. 使用 @Qualifier 凝视指定注入 Bean 的名称

@Autowired
public void setOffice(@Qualifier("office")Office office) {
    this.office = office;
}

@Qualifier("office") 中的office 是 Bean 的名称,所以@Autowired 和@Qualifier 结合使用时,自己主动注入的策略就从
byType 转变成 byName 了。@Autowired 能够对成员变量、方法以及构造函数进行凝视,而@Qualifier 的标注对象是成员变量、方法入參、构造函数入參。

正是因为凝视对象的不同,所以 Spring 不将@Autowired 和@Qualifier 统一成一个凝视类。以下是对成员变量和构造函数入參进行凝视的代码:

对成员变量进行凝视:

清单 14. 对成员变量使用 @Qualifier 凝视

public class Boss {
    @Autowired
    private Car car;

    @Autowired
    @Qualifier("office")
    private Office office;
    …
}

对构造函数入參进行凝视:

清单 15. 对构造函数变量使用 @Qualifier 凝视

public class Boss {
    private Car car;
    private Office office;

    @Autowired
    public Boss(Car car , @Qualifier("office")Office office){
        this.car = car;
        this.office = office ;
 }
}

@Qualifier 仅仅能和@Autowired 结合使用。是对@Autowired 故意的补充。一般来讲。@Qualifier 对方法签名中入參进行凝视会减少代码的可读性,而对成员变量凝视则相对好一些。

时间: 2024-10-14 15:14:48

@Autowired 凝视遇到的问题,@Qualifier 帮助解决这个问题的相关文章

spring的@primary和@qualifier注解解决一个接口多个实现的注入问题

@Primary注解 Spring中有提供一个@Primary注解,具体的作用是在一个接口有多个实现类的情况下,会默认选择其中一种实现,帮助Spring对象的正常注入. 比如说现在有一个接口UserService,它有两个实现类UserServiceImpl1和UserServiceImpl2,根据依赖倒置的原则,在Spring中注入的对象应该是接口,由接口去调用具体的实现. // 接口 public interface UserService { String getUserName(); }

IDEA spirng boot @Autowired注解 mapper出现红色下划线解决方法

例如: 解决方法: 设置中按照下图把钩 去掉 即可 原文地址:https://www.cnblogs.com/wang-yaz/p/9549986.html

@Autowired @Resource @Qualifier的区别

参考博文: http://www.cnblogs.com/happyyang/articles/3553687.html http://blog.csdn.net/revent/article/details/49203619 http://blog.csdn.net/ad921012/article/details/49679745 spring不但支持自己定义的@Autowired注解,还支持几个由JSR-250规范定义的注解,它们分别是@Resource.@PostConstruct以及@

@Resource、@Autowired、@Qualifier的注解注入及区别

在Java代码中可以使用 @Resource  或者 @Autowired 注解方式来进行注入. 虽然 @Resource 和 @Autowried 都可以完成依赖注入,但是他们是有区别的. 一: @Resource 默认是按照名称来装配注入的,只有当找不到与名称匹配的bean才会按照类型来注入. 它有两个属性是比较重要的: ①. name: Spring 将 name 的属性值解析为 bean 的名称, 使用 byName 的自动注入策略 ②. type: Spring 将 type的属性值解

Spring AOP注解通过@Autowired,@Resource,@Qualifier,@PostConstruct,@PreDestroy注入属性的

本文介绍了使用spring注解注入属性的方法. 使用注解以前,注入属性通过类以及配置文件来实现.现在,注入属性可以通过引入@Autowired注解,或者@Resource,@Qualifier,@PostConstruct,@PreDestroy等注解来实现. 使用注解以前我们是怎样注入属性的 类的实现: 1. public class UserManagerImpl implements UserManager { 2. private UserDao userDao; 3. public v

spring注入之使用标签 @Autowired @Qualifier

  使用标签的缺点在于必须要有源码(因为标签必须放在源码上),当我们并没有程序源码的时候,我们只有使用xml进行配置. 例如我们在xml中配置某个类的属性            <bean name="studentService"class="com.bjsxt.service.StudentService"> <property name="studentDao"ref="stuDaoImpl">&

Spring Annotation(@Autowire、@Qualifier)

1 <?xml version="1.0" encoding="UTF-8"?> 2 <beans 3 xmlns="http://www.springframework.org/schema/beans" 4 xmlns:context="http://www.springframework.org/schema/context" 5 xmlns:xsi="http://www.w3.org/20

@Autowired与@Resource的使用方法和差别

一.@Autowired: 1.Spring 2.5 引入了 @Autowired 凝视,它能够对类成员变量.方法及构造函数进行标注,完毕自己主动装配的工作. 通过 @Autowired的使用来消除 set .get方法. 这个注解就是spring能够自己主动帮你把bean里面引用的对象的setter/getter方法省略.它会自己主动帮你set/get. <bean id="userDao" class="..."/> <bean id=&quo

@Autowired 与@Resource的区别(详细)

参考博文: http://www.cnblogs.com/happyyang/articles/3553687.html http://blog.csdn.net/revent/article/details/49203619 http://blog.csdn.net/ad921012/article/details/49679745 spring不但支持自己定义的@Autowired注解,还支持几个由JSR-250规范定义的注解,它们分别是@Resource.@PostConstruct以及@