zoukankan      html  css  js  c++  java
  • 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;
    }
  • 相关阅读:
    C# WebSocket 实现客户端和服务端的通信(二)
    C# WebSocket 实现客户端和服务端的通信(一)
    regsvr32 将dll写入注册表
    Dictionary 添加重复的键值对
    C# Math.Round()的银行家算法
    DataGridView 合并数据相同的行
    获取系统当前日期,分布获取年月日和时分秒
    [Err] ORA-00923: 未找到要求的 FROM 关键字
    正则表达式常用的字符类
    Spring注解作用
  • 原文地址:https://www.cnblogs.com/shirui/p/9427869.html
Copyright © 2011-2022 走看看