当自动装配bean时,遇到多个实现类的情况下,就出现了歧义,例如:
@Autowired
public void setDessert(Dessert dessert) {
this.dessert = dessert;
}
Dessert是一个接口,并且有三个类实现了这个接口,如下所示:
@Component
public class Cake implements Dessert { … }
@Component
public class Cookies implements Dessert { … }
@Component
public class IceCream implements Dessert { … }
三个实现均使用了@Component,在组件扫描时,能够创建它们的bean。但Spring试图自动装配setDessert()中的Dessert参数是,它并没有唯一、无歧义的可选值,Spring无法做出选择,则会抛出NoUniqueBeanDefinitionException的异常。
两种解决办法:
第一种方法:标示首选的bean
如下所示:
@Component
@Primary
public class IceCream implements Dessert { … }
或者,如果通过JavaConfig配置,如下:
@Bean
@Primary
public Dessert iceCream() {
return new IceCream();
}
或者,使用XML配置bean的话,如下:
需要注意的是:不能标示两个或更多的首选bean,这样会引来新的歧义。
第二种方法:限定自动装配的bean
如下所示:
@Autowired
@Qualifier(“iceCream”)
public void setDessert(Dessert dessert) {
this.dessert = dessert;
}
如果不想用默认的bean的名称,也可以创建自定义的限定符
@Component
@Qualifier(“cold”)
public class IceCream implements Dessert { … }
@Autowired
@Qualifier(“cold”)
public void setDessert(Dessert dessert) {
this.dessert = dessert;
}
或者使用JavaConfig配置
@Bean
@Qualifier(“cold”)
public Dessert iceCream() {
return new IceCream();
}
如果出现多个Qualifier,尝试为bean也标示多个不同的Qualifier来表明要注入的bean。
@Component
@Qualifier(“cold”)
@Qualifier(“creamy”)
public class IceCream implements Dessert { … }
@Component
@Qualifier(“cold”)
@Qualifier(“fruity”)
public class Popsicle implements Dessert { … }
@Autowired
@Qualifier(“cold”)
@Qualifier(“creamy”)
public void setDessert(Dessert dessert) {
this.dessert = dessert;
}
但有个问题,Java不允许在同一个条目上重复出现相同类型的注解,编译器会提示错误。
解决办