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;
}

原文地址:https://www.cnblogs.com/shirui/p/9427869.html

时间: 2024-08-02 06:51:51

Spring_总结_04_高级配置(三)之处理歧义的相关文章

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

一.前言 本文承接上一节:Spring_总结_04_高级配置(一)之Profile 在上一节,我们了解到 Profile 为不同环境下使用不同的配置提供了支持,那么Profile到底是如何实现的呢?其实Profile正是通过条件注解来实现的. 条件注解的应用场景举例: (1)希望一个或多个 bean 只有在应用的类路径下包含特定的库时才创建 (2)希望某个bean只有当另外某个特定bean也声明了之后才创建 (3)希望只有某个特定的环境变量设置之后,才会创建某个bean 上述场景能让我们联想到s

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

一.前言 本文承接上一节:Spring_总结_04_高级配置(四)_bean的作用域 当讨论依赖注入的时候,我们通常所讨论的是将一个bean引用注入到另一个bean的属性或者构造参数中.它通常指的是将一个对象与另一个对象进行关联. 但是bean装配的另一个方面指的是将一个值注入到bean的属性或者构造函数中. spring提供了两种在运行时求值的方式: (1)属性占位符 (Property placeholder) (2)Spring表达式语言( SpEL) 原文地址:https://www.c

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

一.前言 本文承接上一节:Spring_总结_04_高级配置(五)_运行时注入值 原文地址:https://www.cnblogs.com/shirui/p/9551412.html

Linux运维实战之Apache服务器的高级配置(虚拟主机、status)

HTTP协议基础知识参考博文:http://sweetpotato.blog.51cto.com/533893/1656137 Apache2.2的基本配置参考博文:http://sweetpotato.blog.51cto.com/533893/1657668 Apache服务的配置分为三段: 1.全局配置(the 'global environment'):对主服务器或虚拟机都有效,且有些功能是服务器自身工作属性: 2.主服务器(main server):主站属性: 3.虚拟主机(Virtu

Cisco ASA 高级配置

Cisco ASA 高级配置 一.防范IP分片攻击 1.Ip分片的原理: 2.Ip分片的安全问题: 3.防范Ip分片. 这三个问题在之前已经详细介绍过了,在此就不多介绍了.详细介绍请查看上一篇文章:IP分片原理及分析. 二.URL过滤 利用ASA防火墙IOS的特性URL过滤可以对访问的网站域名进行控制,从而达到某种管理目的. 实施URL过滤一般分为以下三个步骤: (1) 创建class-map (类映射),识别传输流量. (2) 创建policy-map (策略映射),关联class-map.

Stm32高级定时器(三)

Stm32高级定时器(三) 1 互补输出和死区插入 1.1 死区:某个处于相对无效状态的时间或空间 本来OCX信号与OCXREF时序同相同步,OCXN信号与OCXREF时序反相同步.但为了安全考虑,以OCXREF为参考基准,OCXN和OCX通道将理论上本该导通的时间点往后延时一下,即做从截止切换到导通状态的延时. 特点: ● OCx输出信号与参考信号相同,只是它的上升沿相对于参考信号的上升沿有一个延迟. ● OCxN输出信号与参考信号相反,只是它的上升沿相对于参考信号的下降沿有一个延迟. 1.2

存储学习之--StarWind高级配置(添加新的存储和扩展SIZE)

存储学习之--StarWind高级配置(添加新的存储和扩展SIZE)     在配置完StarWind的存储后,可以按照需求来增加或扩展共享存储设备的容量,以下是具体的操作步骤.  一.添加新的存储(New Target) 选择添加新的target 命名新的target 选择存储设备类型 选择虚拟的方式 以镜像方式添加 建立镜像文件和指定Size 设置共享存储属性,支持Cluster 设置Cache大小 完成创建 创建成功 查看新的存储属性 二.扩展存储的尺寸 选择扩展Size 指定扩展后的Si

存储学习之--StarWind高级配置(设置Client访问规则)

存储学习之--StarWind高级配置(设置Client访问规则)      默认的StarWind允许所有的Client都可以访问iscsi target,可以结合Windows防火墙,建立安全的访问规则,指定只有经过认证的Client才可以访问! 一.配置访问规则 添加新的访问规则 允许指定的ip可以访问 添加源主机(ip) 默认允许访问所有的Target,也可以指定访问指定的Target 访问规则建立成功 二.配置Windows防火墙 选择防火墙的高级配置 允许通过指定port访问 允许访

大型公司网络之——OSPF高级配置(实验)

OSPF高级配置 路由重分发: 一.理解路由重分发: 1.一个单一IP路由协议是管理网络中IP路由的首选方案 2.Cisco ISO能执行多个路由协议,每一个路由协议和该路由协议所服务的网络属于同一个自治系统 3.Cisco ISO使用路由重分发特性以交换不同协议创建的路由信息 二.路由重分发的考虑: 1.度量值 2.管理距离 三.重分发到OSPF域中路由的路径类型: 1.类型1的外部路径(type1 external path,E1) 2.类型2的外部路径(type2 external pat