当候选 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 对方法签名中入參进行凝视会减少代码的可读性,而对成员变量凝视则相对好一些。

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

  1. 从头认识Spring-2.3 注解装配-@autowired(5)-限定器@Qualifier(1)

    这一章节我们来具体讨论一下配合@autowired一起使用的限定器@Qualifier. 1.domain(重点) 蛋糕类: package com.raylee.my_new_spring.my_n ...

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

    Spring中提供了@Primary和@Qualifier注解来解决一个接口多个实现的注入问题. @Primary注解 Spring中有提供一个@Primary注解,具体的作用是在一个接口有多个实现类 ...

  3. listener中@Autowired无法注入bean的一种解决方法

    背景:使用监听器处理业务,需要使用自己的service方法: 错误:使用@Autowired注入service对象,最终得到的为null: 原因:listener.fitter都不是Spring容器管 ...

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

    如图所示,解决方法为: 把勾去掉即可.

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

    在Java代码中可以使用 @Resource  或者 @Autowired 注解方式来进行注入. 虽然 @Resource 和 @Autowried 都可以完成依赖注入,但是他们是有区别的. 一: @ ...

  6. Spring AOP注解通过@Autowired,@Resource,@Qualifier,@PostConstruct,@PreDestroy注入属性的配置文件详解

    本文介绍了使用Spring注解注入属性的方法.使用注解以前,注入属性通过类以及配置文件来实现.现在,注入属性可以通过引入@Autowired注解,或者@Resource,@Qualifier,@Pos ...

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

    本文介绍了使用spring注解注入属性的方法. 使用注解以前,注入属性通过类以及配置文件来实现.现在,注入属性可以通过引入@Autowired注解,或者@Resource,@Qualifier,@Po ...

  8. @Autowired @Resource @Qualifier的区别

    参考博文: http://www.cnblogs.com/happyyang/articles/3553687.html http://blog.csdn.net/revent/article/det ...

  9. Spring Boot + Netty 中 @Autowired, @Value 为空解决

    问题描述 使用 Spring Boot + Netty 新建项目时 Handler 中的 @Autowired, @Value 注解的始终为空值 解决方法 @Component // 1. 添加 @C ...

随机推荐

  1. Java-Spring MVC:JAVA之常用的一些Spring MVC的路由写法以及参数传递方式

    ylbtech-Java-Spring MVC:JAVA之常用的一些Spring MVC的路由写法以及参数传递方式 1.返回顶部 1. 常用的一些Spring MVC的路由写法以及参数传递方式. 这是 ...

  2. wpf 错误 执行了 QueryInterface 调用,请求提供 COM 可见的托管类“BoilerMonitoringV1._0.MapControl”的默认 IDispatch 接口。

    在做wpf嵌入地图时,在自定义的WebBrowser 里面使用JavaScript调用外部方法的时报的错误 在原来的WinForm里 我们只要在窗体类设置的头部设置个 [System.Runtime. ...

  3. Android适配文件dimen自动生成代码

    1:保存下,别人的code import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputSt ...

  4. Fragment_动态加载

    1.新建Fragment的XML布局文件. 2.在activity.xml中添加需要加载Fragment.列如: <?xml version="1.0" encoding=& ...

  5. JavaEE学习记录

    软件152谭智馗 一.JavaEE开发环境配置 1.准备以下压缩包 (1)JDK1.7:jdk1.7.rar (2)开发工具:eclipse-jee-mars-2 (3)项目管理工具:maven-3. ...

  6. 整理Py小demo

    from email.mime.text import MIMEText # 第一个参数就是邮件正文,第二个参数是MIME的subtype, # 传入'plain'表示纯文本,最终的MIME就是'te ...

  7. 多项式拟合的cpp实现

    当我们拥有一组散点图数据时,通常更愿意看到其走势. 对现有数据进行拟合,并输出拟合优度是常用的方法之一. 拟合结果正确性的验证,可以使用excel自带的功能. 下面是c++代码的实现: #ifndef ...

  8. Lazy Stored Properties--无括号时为匿名函数

    第一次使用的时候进行计算和初始化,后面的引用不在进行计算. A lazy stored property is a property whose initial value is not calcul ...

  9. IOS Html富文本渲染方式:DTCoreText、WKWebView、UIWebView的内存占用对比

    在app的内容页(详情页)中,富文本的显示一直是经常需要处理的问题,而通常在后端的富文本编辑中,Html应用比较普遍,所以其实需要处理的Html富文本显示的问题,以下这三种方式肯定不是最优的显示Htm ...

  10. Java中数组获取最大值

    最大值获取:从数组的所有元素中找出最大值. 实现思路: 定义变量,保存数组0索引上的元素 遍历数组,获取出数组中的每个元素 将遍历到的元素和保存数组0索引上值的变量进行比较 如果数组元素的值大于了变量 ...