一、前言

本文承接上一节: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_高级配置(三)_处理歧义的更多相关文章

  1. Spring_总结_04_高级配置(二)_条件注解@Conditional

    一.前言 本文承接上一节:Spring_总结_04_高级配置(一)之Profile 在上一节,我们了解到 Profile 为不同环境下使用不同的配置提供了支持,那么Profile到底是如何实现的呢?其 ...

  2. Spring_总结_04_高级配置(五)_运行时注入值

    一.前言 本文承接上一节:Spring_总结_04_高级配置(四)_bean的作用域 当讨论依赖注入的时候,我们通常所讨论的是将一个bean引用注入到另一个bean的属性或者构造参数中.它通常指的是将 ...

  3. Spring_总结_04_高级配置(四)_bean的作用域

    一.前言 本文承接上一节:Spring_总结_04_高级配置(三)之处理歧义 1.单例bean Spring应用上下文中所有的bean默认都是单例的.也就是说,不管一个bean被注入到其他bean多少 ...

  4. Spring_总结_04_高级配置(六)_Bean的初始化和销毁

    一.前言 本文承接上一节:Spring_总结_04_高级配置(五)_运行时注入值

  5. Spring_总结_04_高级配置(一)_Profile

    一.前言 本文承接上一节:Spring_总结_03_装配Bean(四)之导入与混合配置 这一节,来总结一下profile. 我们在开发软件时,通常会进行跨环境部署.而在跨环境部署时,经常会遇到某些环境 ...

  6. Spring_总结_03_装配Bean(四)_导入与混合配置

    一.前言 本文承接上一节:Spring_总结_03_装配Bean(三)之XML配置 在典型的Spring应用中,我们可能会同时使用自动化和显示配置.同时,可能在某些场景下我们需要混合使用JavaCon ...

  7. [转]JEXUS的高级配置

    转自:http://www.cnblogs.com/xiaodiejinghong/archive/2013/04/14/3019660.html 前一回合,我们对服务器软件Jexus作了简单的介绍, ...

  8. Cisco ASA 高级配置

    Cisco ASA 高级配置 一.防范IP分片攻击 1.Ip分片的原理: 2.Ip分片的安全问题: 3.防范Ip分片. 这三个问题在之前已经详细介绍过了,在此就不多介绍了.详细介绍请查看上一篇文章:I ...

  9. Stm32高级定时器(三)

    Stm32高级定时器(三) 1 互补输出和死区插入 1.1 死区:某个处于相对无效状态的时间或空间 本来OCX信号与OCXREF时序同相同步,OCXN信号与OCXREF时序反相同步.但为了安全考虑,以 ...

随机推荐

  1. unknown facet type would you like to ignore facet from module

    去idea plugin 里面把红色的插件 重新勾选一下,点apply 重启就可以了

  2. SSH终端显示中文乱码

    出现这种关系,首先想到是因为字符集不匹配导致的.打开SSH客户端,连接到linux虚拟机 在虚拟机中输入#cd /etc#cd sysconfig/ 找到i18ncat i18n 会显示当前的编码类型 ...

  3. Linxu下jenkins部署和基本配置

    一.OpenJdk1.8安装(tomcat  和 jenkins都依赖与java) ubuntu apt-cache search openjdk       #使用apt-cache搜索可以直接使用 ...

  4. python中颜色设置

    实现过程: 终端的字符颜色使用转义序列控制的,是文本模式下的系统显示功能,和具体的语言无关. 转义序列是以ESC开头,即用\033来表示(ESC是ASCII码用十进制表示是27,用八进制表示就是033 ...

  5. SourceTree的基本使用---基本介绍/本地开发

    转载自https://www.cnblogs.com/tian-xie/p/6264104.html 1. SourceTree是什么 拥有可视化界面的项目版本控制软件,适用于git项目管理 wind ...

  6. mysql多表查询原理

    转:https://www.cnblogs.com/Toolo/p/3634563.html MySQL的多表查询(笛卡尔积原理)   先确定数据要用到哪些表. 将多个表先通过笛卡尔积变成一个表. 然 ...

  7. Python编程-多态、封装、特性

    一.多态与多态性 1.多态 (1)什么是多态 多态指的是一类事物有多种形态,(一个抽象类有多个子类,因而多态的概念依赖于继承) 序列类型有多种形态:字符串,列表,元组. 动物有多种形态:人,狗,猪 文 ...

  8. MySQL-重做日志 redo log -原理

    [redo log buffer][redo log file]-原理 目录: 1.重做日志写入过程图 2.相关知识点汇总图 3.redo_log_buffer 原理 4.redo_log_file ...

  9. SpringBoot 入门笔记

    1. Spring 4.3中引入了: @GetMapping @PostMapping @PutMapping @DeleteMapping @PatchMapping 2. @RequestMapp ...

  10. java Web 文件上传

    注意:请求实体过大的问题,请修改Nginx服务器的大小(百度参考413 Request Entity Too Large 的解决方法)jsp:<input type="file&quo ...