Spring3.3处理自动装配的歧义性

Posted Java全栈从0到1

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Spring3.3处理自动装配的歧义性相关的知识,希望对你有一定的参考价值。

出现歧义的情景

使用自动装配时,如果有多个bean能匹配上,会产生错误

例如:

//某方法
@Autowired
public void setDessert(Dessert dessert){
    this.dessert = dessert;
}

//有3个类实现了该接口
@Component
public class Cake implements Dessert{...}
@Component
public class Cookies implements Dessert{...}
@Component
public class IceCream implements Dessert{...}

Spring无法从3者中做出选择,抛出NoUniqueBeanDefinitionException异常。

使用@Primary注解标注首选bean

//使用@Component配置bean时,可以使用@Primary注解
@Component
@Primary
public class Cake implements Dessert{...}

//使用@Bean配置bean时,可以使用@Primary注解
@Bean
@Primary
public Dessert iceCream{
    return new IceCream();
}
<!-- 使用XML配置时,设置primary属性 -->
<bean id="iceCream" class="com.desserteater.IceCream" primary="true" />

 使用@Primary时,也会出现多个匹配的bean都标注了primary属性,同样会让Spring出现无法选择的情况,导致错误

 使用@Qualifier注解限定装配的bean

1、使用默认限定符

@Autowired
@Qualifier("iceCream")
public void setDessert(Dessert dessert){
    this.dessert = dessert;
}

 

@Qualifier注解设置的参数是要注入的bean的ID,如果没有为bean设定ID,则为首字母小写的类名(也称这个bean的默认限定符)

2、为bean设置自定义限定符

@Component
@Qualifier("soft")
public class Cake implements Dessert{...}

@Bean
@Qualifier("cold")
public Dessert iceCream{
    return new IceCream();
}

在bean上使用@Qualifier注解,表示为bean设置自定义的限定符。那么自动装载时,就可以使用自定义的限定符进行限定

@Autowired
@Qualifier("cold")
public void setDessert(Dessert dessert){
    this.dessert = dessert;
}

3、使用自定义的限定符注解

假设已经有一个bean使用了限定符cold,结果另外一个bean也需要使用限定符cold,这样也出现了多个匹配的bean也会报错。

解决这个问题的思路是,再为这2个bean增加限定符,继续细化;但是@Qualifier注解并不支持重复注解,不能在一个bean上使用多个@Qualifier注解。

为了解决这个问题,可以使用自定义的限定符注解:

//代替@Qualifier("cold")
@Target({ElementType.CONSTRUCTOR, ElementType.FIELD, ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Qualifier
public @interface Cold{}

//代替@Qualifier("creamy")
@Target({ElementType.CONSTRUCTOR, ElementType.FIELD, ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Qualifier
public @interface Creamy{}

 这样,以下代码,自动装配式使用了2个自定义限定符注解,也可以找到唯一匹配的bean。

@Bean
@Cold
@Creamy
public Dessert iceCream{
    return new IceCream();
}

@Bean
@Cold
public Dessert ice{
    return new Ice();
}

@Autowired
@Cold
@Creamy
public void setDessert(Dessert dessert){
    this.dessert = dessert;
}

 

以上是关于Spring3.3处理自动装配的歧义性的主要内容,如果未能解决你的问题,请参考以下文章

Spring实战之处理自动装配的歧义性

spring装配---处理自动装配的歧义性

spring学习总结——高级装配学习一(处理自动装配的歧义性)

Spring处理自动装配的歧义性

Spring5 解决Bean在自动装配时的歧义性

Spring实战自动装配的歧义性