@Qualifier高级应用---按类别批量依赖注入(QualifierAnnotationAutowireCandidateResolver原理详解)【享学Spring】(下)

本文涉及的产品
传统型负载均衡 CLB,每月750个小时 15LCU
应用型负载均衡 ALB,每月750个小时 15LCU
EMR Serverless StarRocks,5000CU*H 48000GB*H
简介: @Qualifier高级应用---按类别批量依赖注入(QualifierAnnotationAutowireCandidateResolver原理详解)【享学Spring】(下)

@Qualifier高级使用



@Autowired是根据类型进行自动装配的,当Spring容器内同一类型的Bean不止一个的时候,就需要借助@Qualifier来一起使用了。


示例一:


@Configuration
public class WebMvcConfiguration {
    @Qualifier("person1")
    @Autowired
    public Person person;
    @Bean
    public Person person1() {
        return new Person("fsx01", 16);
    }
    @Bean
    public Person person2() {
        return new Person("fsx02", 18);
    }
}


单测代码如下(下同):


public static void main(String[] args) {
    ApplicationContext context = new AnnotationConfigApplicationContext(WebMvcConfiguration.class);
    WebMvcConfiguration bean = context.getBean(WebMvcConfiguration.class);
    // 打印字段的值
    System.out.println(bean.person);
}


运行后打印Person(name=fsx01, age=16),完全符合预期。这也是我们对@Qualifier注解最常规、最简单的使用。


示例二:


若你细心的话你可能注意到了@Qualifier注解它允许继承(@Inherited)、能标注在字段上、方法上、方法参数、类上、注解上。

因此它还能这么用:

@Configuration
public class WebMvcConfiguration {
    @MyAnno // 会把所有标注有此注解的Bean都收入囊中,请List装(因为会有多个)
    @Autowired
    public List<Person> person;
    @MyAnno
    @Bean
    public Person person1() {
        return new Person("fsx01", 16);
    }
    @MyAnno
    @Bean
    public Person person2() {
        return new Person("fsx02", 18);
    }
  // 自定义注解:上面标注有@Qualifier注解
    @Target({FIELD, METHOD})
    @Retention(RetentionPolicy.RUNTIME)
    @Qualifier
    @interface MyAnno {
    }
}


运行单测,打印[Person(name=fsx01, age=16), Person(name=fsx02, age=18)],符合预期。


实例三:


若你不想自定义注解,直接使用@Qualifier注解分类注入也是可以的,如下案例:


@Configuration
public class WebMvcConfiguration {
    @Qualifier("person2")
    @Autowired
    public List<Person> person;
    @Qualifier("person2")
    @Bean
    public Person person1() {
        return new Person("fsx01", 16);
    }
    @Qualifier
    @Bean
    public Person person2() {
        return new Person("fsx02", 18);
    }
    @Qualifier
    @Bean
    public Person person3() {
        return new Person("fsx03", 20);
    }
}


运行的最终结果是:

[Person(name=fsx01, age=16), Person(name=fsx02, age=18)]

它把@Qualifier指定的value值相同的 或者 beanName(或者别名)相同的都注入进来了。这部分匹配代码为


checkQualifier方法:
1、头上标注的注解完全equals(类型和value值都一样,算作匹配成功)
  targetAnnotation != null && targetAnnotation.equals(annotation)
2、Fall back on bean name (or alias) match。若@Qualifier没匹配上,回退到BeanName的匹配,规则为:
   取头上注解的`value`属性(必须有此属性),如果beanName/alias能匹配上次名称,也算最终匹配成功了
  actualValue == null && attributeName.equals(AutowireCandidateQualifier.VALUE_KEY) &&
  expectedValue instanceof String && bdHolder.matchesName((String) expectedValue)


备注:使用在类上、入参上的使用比较简单,此处就不做示范了。

从@Qualifier设计的细节可以看到,注解的value属性并不是必须的,所以它可以很好的使用在联合注解的场景。


关于依赖注入和@Qualifier的使用亦需注意如下细节:


  1. @Autowired可不要写在Object类型的字段上去注入,因为容器内可以找到N多个会报错的。但是List<Object>是可以的(相当于把所有Bean都拿过来~)
  2. 可以利用@Qualifier这个高级特性,实现按需、按类别(不是类型)进行依赖注入,这种能力非常赞,给了框架二次开发设计者提供了更多的可能性


如果说指定value是按照key进行限定/匹配,那么类似@LoadBalanced这种注解匹配可以理解成就是按照莫一类进行归类限定了,并且自由度也更高了。


推荐阅读

为何一个@LoadBalanced注解就能让RestTemplate拥有负载均衡的能力?【享学Spring Cloud】


总结


本文介绍@Qualifier高级应用场景和案例,通过结合@LoadBalanced对此注解的使用,应该说是能给你打开了一个新的视角去看待@Qualifier,甚至看待Spring的依赖注入,这对后续的理解、自定义扩展/使用还是蛮有意义的。

相关实践学习
SLB负载均衡实践
本场景通过使用阿里云负载均衡 SLB 以及对负载均衡 SLB 后端服务器 ECS 的权重进行修改,快速解决服务器响应速度慢的问题
负载均衡入门与产品使用指南
负载均衡(Server Load Balancer)是对多台云服务器进行流量分发的负载均衡服务,可以通过流量分发扩展应用系统对外的服务能力,通过消除单点故障提升应用系统的可用性。 本课程主要介绍负载均衡的相关技术以及阿里云负载均衡产品的使用方法。
相关文章
|
26天前
|
JavaScript 安全 Java
如何使用 Spring Boot 和 Ant Design Pro Vue 实现动态路由和菜单功能,快速搭建前后端分离的应用框架
本文介绍了如何使用 Spring Boot 和 Ant Design Pro Vue 实现动态路由和菜单功能,快速搭建前后端分离的应用框架。首先,确保开发环境已安装必要的工具,然后创建并配置 Spring Boot 项目,包括添加依赖和配置 Spring Security。接着,创建后端 API 和前端项目,配置动态路由和菜单。最后,运行项目并分享实践心得,包括版本兼容性、安全性、性能调优等方面。
130 1
|
10天前
|
JavaScript 安全 Java
如何使用 Spring Boot 和 Ant Design Pro Vue 构建一个具有动态路由和菜单功能的前后端分离应用。
本文介绍了如何使用 Spring Boot 和 Ant Design Pro Vue 构建一个具有动态路由和菜单功能的前后端分离应用。首先,创建并配置 Spring Boot 项目,实现后端 API;然后,使用 Ant Design Pro Vue 创建前端项目,配置动态路由和菜单。通过具体案例,展示了如何快速搭建高效、易维护的项目框架。
88 62
|
7天前
|
人工智能 前端开发 Java
基于开源框架Spring AI Alibaba快速构建Java应用
本文旨在帮助开发者快速掌握并应用 Spring AI Alibaba,提升基于 Java 的大模型应用开发效率和安全性。
基于开源框架Spring AI Alibaba快速构建Java应用
|
8天前
|
JavaScript 安全 Java
如何使用 Spring Boot 和 Ant Design Pro Vue 构建一个前后端分离的应用框架,实现动态路由和菜单功能
本文介绍了如何使用 Spring Boot 和 Ant Design Pro Vue 构建一个前后端分离的应用框架,实现动态路由和菜单功能。首先,确保开发环境已安装必要的工具,然后创建并配置 Spring Boot 项目,包括添加依赖和配置 Spring Security。接着,创建后端 API 和前端项目,配置动态路由和菜单。最后,运行项目并分享实践心得,帮助开发者提高开发效率和应用的可维护性。
21 2
|
21天前
|
人工智能 开发框架 Java
总计 30 万奖金,Spring AI Alibaba 应用框架挑战赛开赛
Spring AI Alibaba 应用框架挑战赛邀请广大开发者参与开源项目的共建,助力项目快速发展,掌握 AI 应用开发模式。大赛分为《支持 Spring AI Alibaba 应用可视化调试与追踪本地工具》和《基于 Flow 的 AI 编排机制设计与实现》两个赛道,总计 30 万奖金。
|
27天前
|
JavaScript 安全 Java
如何使用 Spring Boot 和 Ant Design Pro Vue 构建一个具有动态路由和菜单功能的前后端分离应用
【10月更文挑战第8天】本文介绍了如何使用 Spring Boot 和 Ant Design Pro Vue 构建一个具有动态路由和菜单功能的前后端分离应用。首先,通过 Spring Initializr 创建并配置 Spring Boot 项目,实现后端 API 和安全配置。接着,使用 Ant Design Pro Vue 脚手架创建前端项目,配置动态路由和菜单,并创建相应的页面组件。最后,通过具体实践心得,分享了版本兼容性、安全性、性能调优等注意事项,帮助读者快速搭建高效且易维护的应用框架。
38 3
|
27天前
|
Java Spring 容器
Spring底层原理大致脉络
Spring底层原理大致脉络
|
28天前
|
JavaScript 安全 Java
如何使用 Spring Boot 和 Ant Design Pro Vue 构建一个具有动态路由和菜单功能的前后端分离应用
【10月更文挑战第7天】本文介绍了如何使用 Spring Boot 和 Ant Design Pro Vue 构建一个具有动态路由和菜单功能的前后端分离应用。首先,通过 Spring Initializr 创建 Spring Boot 项目并配置 Spring Security。接着,实现后端 API 以提供菜单数据。在前端部分,使用 Ant Design Pro Vue 脚手架创建项目,并配置动态路由和菜单。最后,启动前后端服务,实现高效、美观且功能强大的应用框架。
34 2
|
15天前
|
存储 Java 数据管理
强大!用 @Audited 注解增强 Spring Boot 应用,打造健壮的数据审计功能
本文深入介绍了如何在Spring Boot应用中使用`@Audited`注解和`spring-data-envers`实现数据审计功能,涵盖从添加依赖、配置实体类到查询审计数据的具体步骤,助力开发人员构建更加透明、合规的应用系统。
|
22天前
|
XML Java 数据格式
Spring IOC容器的深度解析及实战应用
【10月更文挑战第14天】在软件工程中,随着系统规模的扩大,对象间的依赖关系变得越来越复杂,这导致了系统的高耦合度,增加了开发和维护的难度。为解决这一问题,Michael Mattson在1996年提出了IOC(Inversion of Control,控制反转)理论,旨在降低对象间的耦合度,提高系统的灵活性和可维护性。Spring框架正是基于这一理论,通过IOC容器实现了对象间的依赖注入和生命周期管理。
53 0