spring处理自动装配的歧义性

问题场景:spring创建一个Bean需要它是唯一的、没有歧义的,所以当歧义产生时会报错:NoUniqueBeanDefinitionException。

使用@Primary注解

添加了@Primary注解的Bean优先级高,先创建

组件扫面添加@Primary

@Component
@Primary
public class IceCream implement Dessert{}

JavaConfig添加@Primary

@Bean
@Primary
public class IceCream{
    return new IceCream();
}

XML配置

<bean id="iceCream" class="com.dessertteater.IceCream" primary="true"/>

新问题:两个Bean都添加了Primary,又一次使优先级相同,出现歧义性怎么办?

限定符缩小范围

使用@Qualifier配合@Autowired

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

这样在注入dessert时,会匹配bean ID为iceCream的子类进行注入

新问题:如果注入类的bean ID不是默认值,而是自定义的,而且确认自定义的bean ID很麻烦怎么办?

自定义限定符

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

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

不依赖于bean ID进行配对,而是在bean上申明@Qualifier自定义名称,且与注入方法上的@Qualifier自定义名称同名,这样就可以通过@Qualifier限定符自成一体,不与bean ID冲突。

如果想要进一步缩小范围,即同时满足多个条件才进行注入。spring不允许添加多个相同类型注解,即同时添加两个@Qualifier,所以需要自定义@Qualifier注解

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

自定义一个@Cold注解,同样的也可以定义@Creamy

@Component
@Cold
@Creamy
public class IceCream implements Dessert{...}

@Component
@Cold
@Fruity
public class Popsicle implements Dessert{...}

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

则以上3和1匹配,唯一注入iceCream,通过自定义限定符注解,可以使用多个限定符,进一步缩小bean的范围,且避免了Java编译器的限制或者错误,同时相比原始的@Qualifier利用String类型来指定限定符,自定义限定符更加安全。

原文地址:https://www.cnblogs.com/shuiyj/p/13185252.html