处理自动装配的歧义性
仅有一个bean匹配所需结果时自动装配才是有效的
@Autowired
public void setDessert(Dessert dessert){
this.dessert = dessert;
}
@COmponent
public class Cake implements Dessert{...};
@COmponent
public class Cookies implements Dessert{...};
@COmponent
public class IceCream implements Dessert{...};
这时Spring无法做出选择而抛出异常NoUniqueBeanDefinitionException
spring提供了多种可选方案来解决这样的问题
- 将可选bean中的某一个设为首选的bean
- 使用限定符将spring可选范围缩小到只有一个bean可以通过@Primary注解来表达最喜欢的方案
@Component
@Primary
public class IceCream implements DEssert{...}
或者当显示的配置IceCream时
@Bean
@Primary
public Dessert icecream(){
return new IceCream();
}
或在xml中
<bean id="icecream" class="..."
primary="true" />
限定自动装配的bean
@Qualifier注解是使用限定符的主要方式,它可与@Autowired 和 @Inject 注解协同使用
@Autowired
@Qualifier("iceCream") // 括号内为bean的ID
public void setDessert(Dessert dessert){
this.dessert = dessert;
}
但此时限定符和bean的ID是紧耦合的
创建自定义限定符
需要做的就是在bean的声明上添加@Qualifier注解
@Component
@Qualifier("cold")
public class IceCream implements Dessert{
...
}
然后在注入时
@Autowired
@Qualifier("cold")
public Dessert iceCream(){
return new IceCream();
}
Java不允许同一条目上出现相同类型的多个注解,所以@Qualifier("") 不能写多个来缩小范围
但还可以写 使用@Qualifier注解的自定义注解来缩小范围
@Target({ElementType.CONSTRUCTOR,Element.FILED,Element.METHOD,Element.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Qualifier
public @interface Clod{};
@Target({ElementType.CONSTRUCTOR,Element.FILED,Element.METHOD,Element.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Qualifier
public @interface Creamy{};
@Component
@Code
@Creamy
public class IceCream implements Dessert{
...
}
@Autowired
@Cold
@Creamy
public Dessert iceCream(){
return new IceCream();
}