在前面,学习如何装配Bean的时候,或许会发现,有的同类型的Bean智能配置一个
如下:
package com.bean.java; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; /** * Created by IntelliJ IDEA. * Author XueYuan * Data 2017/02/22 * Time 10:08 */ @Configuration public class CDPlayerConfig { /** * @Bean 可以不指定名字 默认为方法名——'dangNianQing' * @Bean(name="XXX") 也可以指定一个名字 */ /*@Bean public CompactDisc dangNianQing() { return new DangNianQing(); }*/ @Bean public CompactDisc randomCd() { int choice = (int) Math.floor(Math.random() * 4); switch (choice) { case 0: return new RandomCd("dangNianQing"); case 1: return new RandomCd("qianNvYouHun"); case 2: return new RandomCd("wo"); default: return new RandomCd("chenMoShiJing"); } } /*@Bean public CDPlay cdPlay(){ return new CDPlay(dangNianQing()); }*/ @Bean public CDPlay cdPlay(CompactDisc compactDisc){ return new CDPlay(compactDisc); } /* @Bean public CDPlay cdPlay(CompactDisc compactDisc){ return new CDPlay(compactDisc); }*/ }
dangNianQing() 与 randomCd() 他们的类型都是 CompactDisc 在 cdPlay() 装配的时候,如果我们没有注释掉其中一个,那么就会报错
因为他不知道我么想要的是哪个,所以只能罢工——NoUniqueBeanDefinitionException异常
那么我们如果不想注释也是可以的,但是我么得告诉它,当发生冲突的时候,我们应该优先选择哪个,这个时候需要我么的 Primary出场了
在java配置中的格式如下:
@Bean @Primary public CompactDisc dangNianQing() { return new DangNianQing(); }
当然 @Bean变成@Component也是一样的
下面就是xml中的配置,在<bean> 中有一个primary的属性来表示为首选的bean
<bean primary="true" id="flyingMounts" class="com.bean.profile.FlyingMounts"/>
我们可以用primary 来解决几个Bean中我们应该首选哪个的问题,但是假如又有一些变态的要求,要我们在首选的中选一个首选的。。
这样以来,首选的primay使用就没有意义了,因为它回到原点了,不知道哪个是首选了。这个时候,我们的Qualifier就可以华丽丽的出场了(等等等等~ )
@Qualifier 注解是使用限定符的主要方式,它可以与@Autowired和@Inject协同使用,在注入的时候我们可以制定注入哪个bean
@Autowired @Qualifier("cdPlay1") CDPlay cdPlay;
表示我要注入名字为cdPlay1的Bean
如下所示,应该是cdPlay1()的方法,bean会自动命名一个id的,以前我们已经学过了
@Bean //@Qualifier("dangNianQing") public CDPlay cdPlay1(CompactDisc compactDisc) { return new CDPlay(compactDisc); } @Bean public CDPlay cdPlay(CompactDisc compactDisc){ return new CDPlay(compactDisc); }
但是假设,我们这个Bean需要被不止一个人使用,假如 cdPaly()和cdPlay1() ,都被需求,那么按照上面的Qualifier应该是这样配置的
@Autowired @Qualifier("cdPlay1") @Qualifier("cdPlay") CDPlay cdPlay;
但是java不允许在同一个目录上面重复相同类型的多个注解,这个时候怎么办呢?
莫慌,我们可以自定义
@Target({ElementType.CONSTRUCTOR,ElementType.FIELD,ElementType.METHOD,ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Qualifier public @interface cdPlay1 { }
这样一来我们可以直接用@cdplay1就可以了,多个的话我们就多创建几个,然后加上去就OK了
上面就说bean歧义性解决的方法,如果错误,欢迎指出,谢谢~