当候选 Bean 数目不为 1 时的应对方法
在默认情况下使用 @Autowired
注释进行自动注入时,Spring 容器中匹配的候选 Bean 数目必须有且仅有一个。当找不到一个匹配的 Bean 时,Spring 容器将抛出BeanCreationException
异常,并指出必须至少拥有一个匹配的 Bean。我们可以来做一个实验:
清单 10. 候选 Bean 数目为 0 时
|
由于
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
… |
我们在 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
对方法签名中入参进行注释会降低代码的可读性,而对成员变量注释则相对好一些。推荐阅读
- =======j2ee|spring用注解实现注入的@resource,@autowired,@inject区别
- jar|springboot项目打成jar包和war包,并部署(快速打包部署)
- 数据库|效率最高的Excel数据导入---(c#调用SSIS Package将数据库数据导入到Excel文件中【附源代码下载】)...
- java人生|35K 入职华为Java开发那天,我哭了(这 5 个月做的一切都值了)
- Java毕业设计项目实战篇|Java项目:在线嘿嘿网盘系统设计和实现(java+Springboot+ssm+mysql+maven)
- 微服务|微服务系列:服务发现与注册-----Eureka(面试突击!你想了解的Eureka都在这里.持续更新中......)