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

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏菩提树下的杨过

Spring Security笔记:Hello World

本文演示了Spring Security的最最基本用法,二个页面(或理解成二个url),一个需要登录认证后才能访问(比如:../admin/),一个可匿名访问(...

2008
来自专栏kl的专栏

Feign-声明式java Http客户端

Feign 是Netfilx开源的一个声明web服务客户端,这便得编写web服务客户端更容易,使用Feign 创建一个接口并对它进行注解,它具有可插拔的注解支持...

7415
来自专栏一个会写诗的程序员的博客

《Spring Boot极简教程》第8章 Spring Boot集成Groovy,Grails开发第8章 Spring Boot集成Groovy,Grails开发小结参考资料

本章介绍Spring Boot集成Groovy,Grails开发。我们将开发一个极简版的pms(项目管理系统)。

1512
来自专栏李蔚蓬的专栏

基于VM14+ Ubuntu 16.04安装VMware Tools(VM同主机file交互的工具)以及使用的骚操作

在安装VMware Tools时,需要修改指向VMware Tools所在(VMware Workstation\linux.iso),在这个路径下有个l...

1635
来自专栏Java3y

Druid数据库连接池就是这么简单

前言 本章节主要讲解Druid数据库连接池,为什么要学Druid数据库连接池呢?? 我的知识储备数据库连接池有两种->C3P0,DBCP,可是现在看起来并不够用...

47811
来自专栏流柯技术学院

linux下安装rzsz

wget http://freeware.sgi.com/source/rzsz/rzsz-3.48.tar.gz

4711
来自专栏一个会写诗的程序员的博客

8.2 Spring Boot集成Groovy、Grails开发小结参考资料

本章介绍Spring Boot集成Groovy,Grails开发。我们将开发一个极简版的pms(项目管理系统)。

1503
来自专栏SpringBoot

SpringCloud Ribbon

Ribbon是一个客户端负载平衡器,它可以很好地控制HTTP和TCP客户端的行为。Feign已经使用Ribbon,所以如果你使用@FeignClient,那么这...

1662
来自专栏史上最简单的Spring Cloud教程

史上最简单的SpringCloud教程 | 第四篇:断路器(Hystrix)

在微服务架构中,根据业务来拆分成一个个的服务,服务与服务之间可以相互调用(RPC),在Spring Cloud可以用RestTemplate+Ribbon和Fe...

2567
来自专栏清晨我上码

第五节 微服务OTRS 补充客户端负载均衡

spring could在客户端负载均衡有两种选择一种是ribbon+restTemplate,另一种是feign。本主要讲解下基于ribbon+rest。当然...

1131

扫码关注云+社区

领取腾讯云代金券