Spring_总结_04_高级配置(三)_处理歧义
一、前言
本文承接上一节:Spring_总结_04_高级配置(二)之条件注解@Conditional
我们前面装配bean时,在Spring容器中,都是只有一个bean能匹配所需的结果。
如果有多个bean能匹配结果的话,Spring就将无法做出选择,这就是自动装配的歧义性。
这一节我们将解决自动装配的歧义性
二、歧义实例
1.实体类
如下,有三个类都继承自Dessert
@Component
public class Cake implements Dessert {...} @Component
public class Cookies implements Dessert {...} @Component
public class IceCream implements Dessert {...}
2.注入bean
@Autowired
public void setDessert(Dessert dessert){
this.dessert = dessert;
}
3.异常
Spring有选择困难症,当Spring尝试自动装配 setDessert() 中的 Dessert 参数时,发现有三个选择,这时它会抛出一个NoUniqueBeanDefinitionException异常,来表示自己无从选择。
可用 @Primary 和 @Qualifier 来解决歧义问题。
三、@Primary
在声明Bean的时候,通过将其中一个可选的bean设置为首选(primary)Bean,能够避免自动装配的歧义性。
被@Primary注解的bean即可首选Bean。
1.配置首选Bean
配置首选Bean有如下两种方式:
(1)在组件类中配合@Component使用
@Component
@Primary
public class IceCream implements Dessert {...}
(2)在配置类中配合@Bean使用
@Bean
@Primary
public Dessert iceCream(){
return new IceCream();
}
2.注入bean
注入bean时,Spring会找到三个可选bean,其中一个是首选bean,因此会选择首选bean进行注入。
@Autowired
public void setDessert(Dessert dessert){
this.dessert = dessert;
}
注意:Spring 有选择困难症,若配置了两个及以上的首选Bean,则Spring有无从选择了。
四、@Qualifier
Spring 的限定符能够将bean限定到唯一一个满足要求的bean.
1. 基于ID的限定符
为@Qualifier注解所设置的参数就是想要注入的bean的 ID
@Autowired
@Qualifier("iceCream") //在注入的时候,指定注入的bean为 iceCream
public void setDessert(Dessert dessert){
this.dessert = dessert;
}
2. 面向特性的限定符
我们可以为bean设置自己的限定符,而不是依赖于将 bean ID 作为限定符。
可在声明Bean或配置Bean时,使用@Qualifier注解设置限定符。
2.1 设置限定符
(1)在声明Bean时,设置限定符
@Component
@Qualifier("cold") //设置限定符为 cold
public class IceCream implements Dessert {...}
(2)在配置Bean时,设置限定符
@Bean
@Qualifier("cold") //设置限定符为 cold
public Dessert iceCream(){
return new IceCream();
}
2.2 使用限定符
@Autowired
@Qualifier("cold") //注入限定符为 cold 的bean
public void setDessert(Dessert dessert){
this.dessert = dessert;
}
3 自定义限定符注解
有时,我们想为bean设置多个限定符,如下:
@Component
@Qualifier("cold") //设置限定符为 cold
@Qualifier("creamy") //设置限定符为 creamy
public class Popsicle implements Dessert {...}
然而,Java不允许在同一个条目上重复出现相同类型的多个注解
为了解决这个问题,我们可以创建自定义的限定符注解。
(1)自定限定符注解
@Cold
@Target({
ElementType.TYPE,
ElementType.CONSTRUCTOR,
ElementType.FIELD,
ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Qualifier
public @interface Cold{ }
@Creamy
@Target({
ElementType.TYPE,
ElementType.CONSTRUCTOR,
ElementType.FIELD,
ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Qualifier
public @interface Creamy{ }
(2)为bean设置多个限定符
@Component
@Cold
@Creamy
public class IceCream implements Dessert {...}
(3)注入bean时,使用多个限定符来限定
@Autowired
@Cold
@Creamy
public void setDessert(Dessert dessert){
this.dessert = dessert;
}
Spring_总结_04_高级配置(三)_处理歧义的更多相关文章
- Spring_总结_04_高级配置(二)_条件注解@Conditional
一.前言 本文承接上一节:Spring_总结_04_高级配置(一)之Profile 在上一节,我们了解到 Profile 为不同环境下使用不同的配置提供了支持,那么Profile到底是如何实现的呢?其 ...
- Spring_总结_04_高级配置(五)_运行时注入值
一.前言 本文承接上一节:Spring_总结_04_高级配置(四)_bean的作用域 当讨论依赖注入的时候,我们通常所讨论的是将一个bean引用注入到另一个bean的属性或者构造参数中.它通常指的是将 ...
- Spring_总结_04_高级配置(四)_bean的作用域
一.前言 本文承接上一节:Spring_总结_04_高级配置(三)之处理歧义 1.单例bean Spring应用上下文中所有的bean默认都是单例的.也就是说,不管一个bean被注入到其他bean多少 ...
- Spring_总结_04_高级配置(六)_Bean的初始化和销毁
一.前言 本文承接上一节:Spring_总结_04_高级配置(五)_运行时注入值
- Spring_总结_04_高级配置(一)_Profile
一.前言 本文承接上一节:Spring_总结_03_装配Bean(四)之导入与混合配置 这一节,来总结一下profile. 我们在开发软件时,通常会进行跨环境部署.而在跨环境部署时,经常会遇到某些环境 ...
- Spring_总结_03_装配Bean(四)_导入与混合配置
一.前言 本文承接上一节:Spring_总结_03_装配Bean(三)之XML配置 在典型的Spring应用中,我们可能会同时使用自动化和显示配置.同时,可能在某些场景下我们需要混合使用JavaCon ...
- [转]JEXUS的高级配置
转自:http://www.cnblogs.com/xiaodiejinghong/archive/2013/04/14/3019660.html 前一回合,我们对服务器软件Jexus作了简单的介绍, ...
- Cisco ASA 高级配置
Cisco ASA 高级配置 一.防范IP分片攻击 1.Ip分片的原理: 2.Ip分片的安全问题: 3.防范Ip分片. 这三个问题在之前已经详细介绍过了,在此就不多介绍了.详细介绍请查看上一篇文章:I ...
- Stm32高级定时器(三)
Stm32高级定时器(三) 1 互补输出和死区插入 1.1 死区:某个处于相对无效状态的时间或空间 本来OCX信号与OCXREF时序同相同步,OCXN信号与OCXREF时序反相同步.但为了安全考虑,以 ...
随机推荐
- OC、C#与JAVA语法特点一些异同(差集&交集)
C#对JAVA: 1.扩展方法 2.部分类 3.动态对象 4.匿名返回类型 5.表达式树 6.Linq 7.没有函数指针,委托,事件的直接提供方式 8.JAVA接口不规定以I开头,这个很烂的思想! J ...
- spring boot 如何将没有注解的类@Autowired
等于将类交给spring管理,也就是IOC. 注解@Autowired是自动装配,也就是spring帮你创建对象,当然前提是这个@Autowired的类已经配置成Bean了,spring配置bean文 ...
- 010-spring事务管理
一.Spring的事务传播行为 事务是从哪里传播到哪里? 是从方法A传播至方法B. Spring事务类型详解: PROPAGATION_REQUIRED--如果当前没有事务,就新建一个事务.如果有,就 ...
- C#如何打印RichTextBox控件的内容
本任务的内容 摘要 创建 RichTextBoxPrintCtrl 控件 测试控件 参考 概要 本分步指南介绍了如何打印 RichTextBox 控件的内容.RichTextBox 控件没有提供任 ...
- Ubuntu 下 java 版本的切换
切换的方法很简单,使用下面的两个命令即可: update-alternatives --config java update-alternatives --config javac eg: root@ ...
- 使用PLSQL Developer和DbVisualizer、SQLDBx查询oracle数据库时出现乱码
使用PLSQL Developer和DbVisualizer查询oracle数据库时,出现查询数据中文乱码情况. 查看了一下数据库编码格式select * from v$nls_parameters; ...
- 小程序 height100% Android ios上的不同表现
Android还是按原图显示 ios,会完全覆盖
- $ListView的优化机制和滑动时数据错乱的讨论
Refer:http://www.myexception.cn/mobile/1612364.html (一)Android ListView的基本用法 1.创建一个实体类Person,为其添加Get ...
- Python自然语言处理 - 系列三
有监督分类过程 ![enter image description here][1]例子:涉及一个特征器,给定一个姓名分析出是男性名字还是女性名字 分析:男性和女性的名字有一些鲜明的特点.以a,e 和 ...
- 跨平台移动开发_Android 平台使用 PhoneGap 方法
PhoneGap 下载地址http://phonegap.com/install/ 1.打开 Eclipse,在文件菜单下面点击 创建> Android Application Proj ...