spring四 处理自动装配的歧义性

论坛 期权论坛 编程之家     
选择匿名的用户   2021-6-2 15:56   1561   0
通常bean的自动装配能够给我们提供很大的方便,它会减少装配应用程序组件时所需要的显示配置的麻烦。不过,仅有一个bean匹配所需的结果时,自动装配才是有效的。如果符合条件的bean不只一个,这时就会阻碍Spring自动装配属性、构造器参数或方法参数。
下面我们就来制造一种自动装配歧义性的情况:
public interface Dessert {}

@Component
public class Cake implements Dessert{
@Component
public class IceCream implements Dessert {}
@Component
public class Cookies implements Dessert{}
@Component
private Dessert dessert;
因为这三个实现均使用了@Component注解,在组件扫描的时候,能够发现它们并将其创建为Spring应用上下文里面的bean。然后,当Spring试图自动装配setDessert()中的Dessert参数时,它并没有唯一、无歧义的可选值。在从多种甜点中做出选择时,尽管大多数人并不会有什么困难,但是Spring却无法做出选择。Spring此时别无他法,只好宣告失败并抛出异常。更精确地讲,Spring会抛出NoUniqueBeanDefinitionException
解决办法:

标示首选的bean

@Component
@Primary
public class IceCream implements Dessert {}

或者在如果你通过Java配置显式地声明IceCream,那么@Bean方法应该如下所示

@Configuration
public class IceCreamBean {

    @Bean
    @Primary
    public Dessert iceCream(){
        return new IceCream();
    }
}

果你使用XML配置bean的话,同样可以实现这样的功能。<bean>元素有一个primary属性用来指定首选的bean:

<bean id="iceCream" class="com.ambiguity.service.impl.IceCream" primary="true" />

但是,如果你标示了两个或更多的首选bean,那么它就无法正常工作了

2.限定自动装配的bean

设置首选bean的局限性在于@Primary无法将可选方案的范围限定到唯一一个无歧义性的选
项中。它只能标示一个优先的可选方案。当首选bean的数量超过一个时,我们并没有其他的
方法进一步缩小可选范围。Spring的限定符能够在所有可选的bean上进行缩小范围的操作,最终能够达到只

有一个bean满足所规定的限制条件。

@Qualifier注解是使用限定符的主要方式。它可以与@Autowired和@Inject协同使用,在注入的时候指定想要注入进去的是哪个bean。

@AutoWired
@Qualifier("iceCream")
public void setDessert(Dessert dessert){
      this.dessert =dessert;  
}


这里所设置的参数就是想要注入bean的ID。所有使用@Component注解声明的类都会创建为bean,并且bean的ID为首字母变为小写的类名,因此@Qualifier("iceCream")指向的是组件扫描时所创建的bean并且这个bean是IceCream类的实例。但是,字符串类型的参数是不安全的,如果修改类名,这里也会受到影响,所以我们需要创建自定义的限定符,所需要做的仅仅是在IceCream类上面添加@Qualifier("cold"):

@Component
@Qualifier("cold")
public class IceCream implements Dessert{...}

或者在显式模式中:

@Bean
@Qualifier("cold")
public Dessert iceCream(){
        return new IceCream();
}

相应的setter方法上也将参数设置为cold即可。

可是,如果有另外一个bean也同样使用了cold限定符呢,还是会出现歧义,而java不允许同一个条目上重复出现相同类型的多个注解,否则编译器会报错,所以我们需要创建自定义的限定符注解,借助这样的注解来表达bean所希望限定的特性


如果有两个面向特性的限定符要比基于bean ID的限定符更好一些。但是,如果多个bean都具备相同特性的话,这种做法也会出现问题在自动装配Dessert bean的时候,我们再次遇到了歧义性的问题,需要使用更多的限定符来将可选范围限定到只有一个bean。Java不允许在同一个条目上重复出现相同类型的多个注解所有不能用两条@Qualifier

这样我们将不再使用@Qualifier("cold"),而是使用自定义的注解



分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:3875789
帖子:775174
精华:0
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP