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处理自动装配的歧义性的主要内容,如果未能解决你的问题,请参考以下文章