本文主要是介绍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类型来指定限定符,自定义限定符更加安全。
这篇关于spring处理自动装配的歧义性的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!