SpringInAction--Bean自动装配的歧义性处理

在前面,学习如何装配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歧义性解决的方法,如果错误,欢迎指出,谢谢~

 

posted @ 2017-02-23 23:51  大园子  阅读(331)  评论(0编辑  收藏  举报