Spring注解@Qualifier的详细用法你知道几种
环境:springboot2.3.10
一般使用在项目中使用@Qualifier来限定注入的Bean。
由于项目中我习惯用@Resource注解,所以这里先对@Autowired和@Resource进行个简单的说明。
@Autowired和@Resource区别
相同点:
@Autowired与@Resource都可以用来装配Bean。都可以写在字段上,或写在setter方法上。
区别:
1、@Autowired(Spring注解)
默认按类型装配,默认情况下必须要求依赖对象必须存在(不存在会报错),可以通过required=false属性设置非必须 ,如果我们想使用名称装配可以结合@Qualifier注解进行使用,示例如下:
@Autowired(required = false)private Date date ; @Autowired@Qualifier("birth")private Date birthday ;
当系统中存在多个相同类型的Bean时,如果不使用@Qualifier程序启动是会报错
@Beanpublic Date d1() {return new Date() ; }@Beanpublic Date d2() {return new Date() ; }@Autowiredprivate Date date ;
文章图片
2、@Resoure(JavaEE注解)
默认按照名称进行装配,可以通过name属性指定名称,如果没有指定name属性,当注解写在字段上时,默认取字段名进行查找注入,如果写在setter方法上默认取属性名进行装配。当找不到与名称匹配的bean时才按照类型进行装配。但是需要注意的是,如果name属性一旦指定,就只会按照名称进行装配。示例:
还是上面的例子
@Resourceprivate Date date
启动后会报错:
Caused by: org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'java.util.Date' available: expected single matching bean but found 2: d1,d2【Spring注解@Qualifier的详细用法你知道几种】因为我们没有以date为名称的bean,所以会按照类型进行注入,但是类型又有两个Date的Bean。将date改为d1或者d2或者指明name属性。
@Resource("d1")private Date date
@Autowired和@Resource就介绍到这里了
常规用法限定注入类 通过上面的示例我们已经了解了@Qualifier的主用
@Autowired@Qualifier("d1")private Date date ;
用来限定注入的Bean的名称。这种用法也是很好的理解,接下来我们介绍通过@Qualifier来筛选限定注入对象。
@Qualifier筛选注入对象 直接使用@Qualifier限定
@Qualifier@Beanpublic Date d1() {return new Date() ; }@Beanpublic Date d2() {return new Date() ; }@Resourceprivate Listdates = Collections.emptyList() ;
打印dates集合:
文章图片
集合中注入了2个Date Bean。
修改代码:
@Resource@Qualifierprivate Listdates = Collections.emptyList() ;
在属性上加入@Qualifier注解
执行结果:
文章图片
只注入了一个Date Bean。
@Qualifier起到了一个筛选的作用只有Bean上加有@Qualifier注解的Bean才会被收集注入。
自定义注解限定注入Bean
@Target({ ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD })@Retention(RetentionPolicy.RUNTIME)@Documented@Inherited@Qualifierpublic @interface FK {}
注意:该自定义注解上添加有@Qualifier注解。
@FK@Beanpublic Date d1() {return new Date() ; }@Beanpublic Date d2() {return new Date() ; }@Resource@FKprivate Listdates = Collections.emptyList() ;
运行:
文章图片
注入了一个Date Bean。
该使用示例在Spring Cloud中Ribbon是也有应用的。
在使用Ribbon做负载均衡时,在配置RestTemplate时会加入如下注解:
@LoadBalanced@Beanpublic RestTemplate restTemplate() {return new RestTemplate() ; }@Target({ ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD })@Retention(RetentionPolicy.RUNTIME)@Documented@Inherited@Qualifierpublic @interface LoadBalanced {}
在Ribbon的自动配置类中:
文章图片
这里指明了只收集带有@LoadBalanced注解的RestTemplate对象。然后给对应RestTemplate设置拦截器来实现直接通过服务名就能调用接口。接下来简单介绍下RestTemplate怎么实现负载均衡。
文章图片
拦截器中就开始获取服务名,然后调用createRequest方法来将serviceName换成真实的IP
文章图片
ServiceRequestWrapper类
文章图片
进入ServiceRequestWrapper类,该类重写了HttpRequest对象的getURI方法
文章图片
通过负载均衡重写构造URI
文章图片
这里相关的Ribbon相关实现的负载均衡我们都省略了,这里给出几个核心的类:
LoadBalancerAutoConfiguration.java 负载均衡自动配置
RibbonClientConfiguration.java ribbon客户端相关配置,比如:负载均衡的算法,服务列表的更新,ping健康检查等。如果想自定义实现负载均衡算法可以实现IRule类。
完毕!!!
到此这篇关于Spring注解@Qualifier这种用法你知道吗?的文章就介绍到这了,更多相关Spring注解@Qualifier内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
推荐阅读
- Activiti(一)SpringBoot2集成Activiti6
- SpringBoot调用公共模块的自定义注解失效的解决
- 解决SpringBoot引用别的模块无法注入的问题
- 2018-07-09|2018-07-09 Spring 的DBCP,c3p0
- spring|spring boot项目启动websocket
- 生活与游戏日记(第182篇)(〔成长瞬间〕关注解决问题2019.10)
- Spring|Spring Boot 整合 Activiti6.0.0
- Spring集成|Spring集成 Mina
- springboot使用redis缓存
- Spring|Spring 框架之 AOP 原理剖析已经出炉!!!预定的童鞋可以识别下发二维码去看了