一.歧义性

当我们使用spring的注解进行自动装配bean时,如果不仅有一个bean能够匹配结果的话,会抛出NoUniqueBeanDefinitionException:

例如本例中

当spring尝试为DuckBasket类注入duck属性时就会抛出该异常

因为greenDuck类,和redDuck类都实现了Duck接口,换言之,Duck类型有两个实现类,也就是有两个可以匹配的bean造成了歧义性,spring不知道该注入哪个bean给该属性。

二.解决方法

(1)标识首选的bean--通过@primary注解

加上@primary注解之后,GreenDuck类就会成为Duck类型的bean中的首选bean,换言之当要注入Duck类型的属性时,会注入GreenDuck类型的实例。

或者当你使用java显示配置bean时,@Primary注解也可以与@bean注解一起使用

或者当你使用XML配置Bean时,可将bean的Primary属性设置为true

(2)给bean配置限定符--@Qualifier注解

@primary 注解缺点在于无法存在多个同类型的首选bean,例如上例中把RedDuck类也用@Primary注解标识,装配时则又会产生NoUniqueBeanDefinitionException:

因为此时RedDuck类与GreenDuck类又处在相同优先级上了。

@Qualifier注解的使用方式如下

首先用@Qualifier注解给bean添加限定符,然后在要注入该bean的地方再用@Qualifier注解给该属性配置限定符,告诉spring该装配哪个bean。

当你使用Java配置类显示配置bean时,@Qualifier注解也可以和@bean注解一起使用

注:若不在bean上添加@Qualifier注解,即上例中GreenDuck类不添加@Qualifier注解,在DcukBasket类该属性中可将@Qualifier注解改为

@Qualifier("greenDuck"),即Spring的自动装配方案中,bean的默认ID为类名的第一个字母改成小写,后面不变,默认限定符也是如此,但是使用

默认限定符当类名发生变化时,会导致spring装配失败,因为此时默认限定符也发生了改变,所以建议使用图片中自定义限定符的方式进行注解。

(3)使用自定义限定符注解

在(2)中,若RedDuck类也添加了与GreenDuck类相同的注解,则又会导致歧义性,因为此时该限定符下的bean同样不止一个

当遇到这种情况时,我们可能想到在GreenDuck类上在添加限定符来进一步限定唯一的Bean,如下图

但是java不支持相同的注解出现两次,所以此时就需要我们创建自定义限定符注解,创建方式如下

注解使用关键词@interface定义,

@Qualifier注解修饰该自定义注解是一个限定符注解

其中@Target @Retention的作用如下

@Retention :用来说明该注解类的生命周期。它有以下三个参数:

RetentionPolicy.SOURCE  : 注解只保留在源文件中

RetentionPolicy.CLASS  : 注解保留在class文件中,在加载到JVM虚拟机时丢弃

RetentionPolicy.RUNTIME  : 注解保留在程序运行期间,此时可以通过反射获得定义在某个类上的所有注解。

@Target :  用来说明该注解可以被声明在那些元素之前。

ElementType.TYPE:说明该注解只能被声明在一个类前。

ElementType.FIELD:说明该注解只能被声明在一个类的字段前。

ElementType.METHOD:说明该注解只能被声明在一个类的方法前。

ElementType.PARAMETER:说明该注解只能被声明在一个方法参数前。

ElementType.CONSTRUCTOR:说明该注解只能声明在一个类的构造方法前。

ElementType.LOCAL_VARIABLE:说明该注解只能声明在一个局部变量前。

ElementType.ANNOTATION_TYPE:说明该注解只能声明在一个注解类型前。

ElementType.PACKAGE:说明该注解只能声明在一个包名前。

创建好限定符注解后,就可以是用该注解限定bean了,例如

此时便可以在一个限定符的基础上进一步限定唯一bean了,由于自定义的限定符注释不存在同名的情况,所以自定义限定符是可以一层一层限定的

spring装配---处理自动装配的歧义性的更多相关文章

  1. Spring学习笔记--自动装配Bean属性

    Spring提供了四种类型的自动装配策略: byName – 把与Bean的属性具有相同名字(或者ID)的其他Bean自动装配到Bean的对应属性中. byType – 把与Bean的属性具有相同类型 ...

  2. Spring(六)之自动装配

    一.自动装配模型 下面是自动连接模式,可以用来指示Spring容器使用自动连接进行依赖注入.您可以使用元素的autowire属性为bean定义指定autowire模式. 可以使用 byType 或者  ...

  3. Spring 由构造函数自动装配

    Spring 由构造函数自动装配,这种模式与 byType 非常相似,但它应用于构造器参数. Spring 容器看作 beans,在 XML 配置文件中 beans 的 autowire 属性设置为 ...

  4. 6、Spring教程之自动装配

    自动装配说明 自动装配是使用spring满足bean依赖的一种方法 spring会在应用上下文中为某个bean寻找其依赖的bean. Spring中bean有三种装配机制,分别是: 在xml中显式配置 ...

  5. 【面试普通人VS高手系列】Spring Boot中自动装配机制的原理

    最近一个粉丝说,他面试了4个公司,有三个公司问他:"Spring Boot 中自动装配机制的原理" 他回答了,感觉没回答错误,但是怎么就没给offer呢? 对于这个问题,看看普通人 ...

  6. Spring(二)-生命周期 + 自动装配(xml) +自动装配(注解)

    1.生命周期 **Spring容器的 bean **的生命周期: 1.1 默认生命周期 1.1.1 生命周期 调用构造方法,创建实例对象: set方法,给实例对象赋值: init 初始化方法 初始化对 ...

  7. 装配SpringBean(五)--注解装配之自动装配

    在spring ioc容器中,spring要先完成bean的定义和生成,然后需要需要注入的资源,在上一篇的扫描组件中就是这样实现的.而自动装配中我们只需要定义和生成一个bean,发现bean的过程将由 ...

  8. Spring - 配置Bean - 自动装配 关系 作用域 引用外部属性文件

    1 Autowire自动装配1.1 使用:只需在<bean>中使用autowire元素<bean id="student" class="com.kej ...

  9. java之Spring(IOC)装配Bean(手动装配、自动装配、注解装配)

    在上一篇控制反转中我们看到了依靠一个Bean文件来实现对代码的控制,可谓十分便捷,再也不用去实例化对象了,2333~~~ 1.手动装配 <bean id="todo" cla ...

随机推荐

  1. JVM参数OmitStackTraceInFastThrow:不打印NullPointerException异常堆栈

    查看线上日志,遇到一个诡异的问题,就是系统大量空指针的异常,但是没有打印堆栈,导致不方便定位问题. 经过一番代码调试,确定并非程序代码问题.没有线索之后,从Google找到了答案:是因为在server ...

  2. js判断本地是否安装app

    var ua = navigator.userAgent.toLowerCase(); 1.判断是否是微信 function isWeixinBrowser() { return (/micromes ...

  3. Firefox下载自动保存

    profile.setPreference("browser.download.folderList", 2); profile.setPreference("brows ...

  4. UVALive 4849 String Phone(2-sat、01染色)

    题目一眼看去以为是4-sat... 题意:给n(n<=3000)个黑方块的坐标,保证黑方块没有公共边.对于每个黑方块选一个角作为结点,使得所选结点满足输入的一个无向图.其中距离为曼哈顿距离.输出 ...

  5. 腾讯QQ形象18年变迁史,最早的QQ企鹅形象居然长这样!

    1999年,腾讯创建之初,这是当时QQ的形象,现在看起来很滑稽,又高又瘦.当时公司并没有专职的设计师,所以这个形象就凑合着用了. 后来,腾讯也觉着上一个形象做的不是特别好,于是在2000年的时候,公司 ...

  6. WPF MVVM中在ViewModel中关闭或者打开Window

    这篇博客将介绍在MVVM模式ViewModel中关闭和打开View的方法. 1. ViewModel中关闭View public class MainViewModel { public Delega ...

  7. Intellij IDEA中的Mybatis Plugin破解

    具体的破解过程请看:https://github.com/luyanliang/profile/blob/master/idea/plugin/MybatisPlugin/Mybatis-Plugin ...

  8. java返回一个简单的日历

    import java.text.*; //首先得导包 import java.util.*; public class hw2 { /** * 计算日期差 返回的天数 * @param dstr1 ...

  9. H5中REM中使用的规则

    /*REM单位换算方法 iphone6适配*/ function resizeRoot(){ var Dpr = 1, uAgent = window.navigator.userAgent; var ...

  10. 对LR关联的一些理解

    从接触LR关联的迷茫,到现在略有感悟,小记期间的一些理解. 一开始认识关联是在LR自带学习例子,需要关联session,也知道了自动关联,手动关联以及边录制边关联. 在使用关联的过程中,也学习了web ...