首页 技术 正文
技术 2022年11月8日
0 收藏 733 点赞 1,704 浏览 1837 个字

一.歧义性

当我们使用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了,由于自定义的限定符注释不存在同名的情况,所以自定义限定符是可以一层一层限定的

相关推荐
python开发_常用的python模块及安装方法
adodb:我们领导推荐的数据库连接组件bsddb3:BerkeleyDB的连接组件Cheetah-1.0:我比较喜欢这个版本的cheeta…
日期:2022-11-24 点赞:878 阅读:9,488
Educational Codeforces Round 11 C. Hard Process 二分
C. Hard Process题目连接:http://www.codeforces.com/contest/660/problem/CDes…
日期:2022-11-24 点赞:807 阅读:5,903
下载Ubuntn 17.04 内核源代码
zengkefu@server1:/usr/src$ uname -aLinux server1 4.10.0-19-generic #21…
日期:2022-11-24 点赞:569 阅读:6,736
可用Active Desktop Calendar V7.86 注册码序列号
可用Active Desktop Calendar V7.86 注册码序列号Name: www.greendown.cn Code: &nb…
日期:2022-11-24 点赞:733 阅读:6,487
Android调用系统相机、自定义相机、处理大图片
Android调用系统相机和自定义相机实例本博文主要是介绍了android上使用相机进行拍照并显示的两种方式,并且由于涉及到要把拍到的照片显…
日期:2022-11-24 点赞:512 阅读:8,127
Struts的使用
一、Struts2的获取  Struts的官方网站为:http://struts.apache.org/  下载完Struts2的jar包,…
日期:2022-11-24 点赞:671 阅读:5,289