巧妙注入的奥秘:在 Spring 中优雅地使用 List 和 Map

news/2024/11/15 11:40:40/

文章目录

      • 一、注入 List:同类项,一次拿下
      • 二、注入 Map:当键值对遇上多态
      • 三、进阶:使用 Qualifier 灵活注入
      • 四、总结
      • 总结
      • 推荐阅读文章

在 Spring 框架里,我们经常需要将不同的组件组织到集合中,比如在注入多个服务实例时,将它们置于一个 ListMap 集合中供后续灵活调用。这种设计不仅简洁且可扩展,同时也让代码更具可维护性。今天,我们就来一起看看如何在 Spring 中用最优雅的方式注入这些集合!

一、注入 List:同类项,一次拿下

在 Spring 中,List 注入可以让我们轻松地将一组同类的 Bean 注入到一个集合中。假设我们有多个实现了 OrderService 接口的类:

public interface OrderService {void processOrder();
}@Component
public class RegularOrderService implements OrderService {public void processOrder() {System.out.println("Processing regular order");}
}@Component
public class SpecialOrderService implements OrderService {public void processOrder() {System.out.println("Processing special order");}
}

我们可以在使用这些实现的类中通过 List<OrderService> 来一键注入:

@Component
public class OrderProcessor {private final List<OrderService> orderServices;public OrderProcessor(List<OrderService> orderServices) {this.orderServices = orderServices;}public void processAllOrders() {orderServices.forEach(OrderService::processOrder);}
}

通过这种方式,Spring 会自动把实现 OrderService 的所有 Bean 注入到 orderServices 列表中。这样一来,不管有多少个实现,只要实现 OrderService,我们就不需要额外修改代码,非常灵活。

二、注入 Map:当键值对遇上多态

如果我们希望按名称获取服务,比如用 Map<String, OrderService>,也是很容易实现的。假如 RegularOrderServiceSpecialOrderService 分别需要按名称访问,那么我们只需改写注入为 Map 类型:

@Component
public class OrderProcessorWithMap {private final Map<String, OrderService> orderServiceMap;public OrderProcessorWithMap(Map<String, OrderService> orderServiceMap) {this.orderServiceMap = orderServiceMap;}public void processOrderByType(String type) {OrderService service = orderServiceMap.get(type);if (service != null) {service.processOrder();} else {System.out.println("Unknown order type");}}
}

在使用时,只需指定名称即可找到对应的 OrderService。Spring 会自动将 Bean 名称作为 Map 的键,实例作为值,非常方便地按需调用!

三、进阶:使用 Qualifier 灵活注入

当我们想要对注入的集合进行精确控制时,可以使用 @Qualifier 注解。比如我们只希望注入特殊的 OrderService 实现类:

@Component
public class FilteredOrderProcessor {private final List<OrderService> specialServices;public FilteredOrderProcessor(@Qualifier("special") List<OrderService> specialServices) {this.specialServices = specialServices;}public void processSpecialOrders() {specialServices.forEach(OrderService::processOrder);}
}

在这里,我们可以通过 @QualifierOrderService 添加一个名称,在需要的时候选择性注入,避免了注入无关的实现。

四、总结

利用 Spring 的 ListMap 注入功能,可以轻松管理多实现类的依赖,增强代码的模块化和可读性。尤其在扩展服务的场景下,使用集合注入能够让代码随需求增长而从容扩展。


希望这样的讲解能让你在实际项目中得心应手地管理多类服务注入,让代码更整洁优雅!

总结

作为一名拥有多年开发经验的老程序员,我深知,技术的学习永无止境,项目的挑战也源源不断。通过这篇文章,我希望你能从我的经验中获得一些启发,避免那些常见的弯路,让你的开发之路走得更加顺畅。如果你能将这些技巧运用到自己的项目中,相信一定能提高自己的开发效率,并在团队中脱颖而出。

推荐阅读文章

  • 由 Spring 静态注入引发的一个线上T0级别事故(真的以后得避坑)
  • 如何理解 HTTP 是无状态的,以及它与 Cookie 和 Session 之间的联系
  • HTTP、HTTPS、Cookie 和 Session 之间的关系
  • 什么是 Cookie?简单介绍与使用方法
  • 什么是 Session?如何应用?
  • 使用 Spring 框架构建 MVC 应用程序:初学者教程
  • 有缺陷的 Java 代码:Java 开发人员最常犯的 10 大错误
  • 如何理解应用 Java 多线程与并发编程?
  • 把握Java泛型的艺术:协变、逆变与不可变性一网打尽
  • Java Spring 中常用的 @PostConstruct 注解使用总结
  • 如何理解线程安全这个概念?
  • 理解 Java 桥接方法
  • Spring 整合嵌入式 Tomcat 容器
  • Tomcat 如何加载 SpringMVC 组件
  • “在什么情况下类需要实现 Serializable,什么情况下又不需要(一)?”
  • “避免序列化灾难:掌握实现 Serializable 的真相!(二)”
  • 如何自定义一个自己的 Spring Boot Starter 组件(从入门到实践)
  • 解密 Redis:如何通过 IO 多路复用征服高并发挑战!
  • 线程 vs 虚拟线程:深入理解及区别
  • 深度解读 JDK 8、JDK 11、JDK 17 和 JDK 21 的区别
  • 10大程序员提升代码优雅度的必杀技,瞬间让你成为团队宠儿!
  • “打破重复代码的魔咒:使用 Function 接口在 Java 8 中实现优雅重构!”
  • Java 中消除 If-else 技巧总结
  • 线程池的核心参数配置(仅供参考)
  • 【人工智能】聊聊Transformer,深度学习的一股清流(13)
  • Java 枚举的几个常用技巧,你可以试着用用

http://www.ppmy.cn/news/1547190.html

相关文章

MySQL 8.0特性-自增变量的持久化

MySQL 8.0特性-自增变量的持久化 在MySQL 8.0之前&#xff0c;自增主键AUTO_INCREMENT的值如果大于max(primary key)1&#xff0c;在MySQL重启后&#xff0c;会重置AUTO_INCREMENTmax(primary key)1&#xff0c;这种现象在某些情况下会导致业务主键冲突或者其他难以发现的问题…

leetcode61. Rotate List

Given the head of a linked list, rotate the list to the right by k places. 给你一个链表的头节点 head &#xff0c;旋转链表&#xff0c;将链表每个节点向右移动 k 个位置。 Input: head [1,2,3,4,5], k 2 Output: [4,5,1,2,3] class Solution: def rotateRight(self, …

嵌入式硬件实战提升篇(一)-泰山派RK3566制作多功能小手机

引言&#xff1a;主要针对于嵌入式全栈内容的知识点汇总并对于linux等相关驱动知识点进行串联&#xff0c;用大家参考学习&#xff0c;并用到了嘉立创提供的泰山派RK3566作为学习的主控。 实物演示如下所示&#xff1a; 目录 一、硬件设计 1.转接电路 2.背光电路 3.音频接…

wordpress functions文件的作用及详细说明

WordPress的functions.php文件是一个非常重要的主题文件&#xff0c;它允许开发者和用户向网站添加自定义代码片段&#xff0c;从而修改网站功能或添加新内容。以下是functions.php文件的主要作用和一些详细说明&#xff1a; 1. 自定义功能添加&#xff1a; functions.php文件…

什么是python爬虫?

今天就来给大家介绍一下什么是python爬虫。 Python爬虫是一种自动化程序&#xff0c;用于在互联网上浏览和提取信息。它通过模拟人类用户访问网页的行为&#xff0c;发送HTTP请求&#xff0c;获取网页内容&#xff0c;然后解析这些内容以提取所需数据 。以下是关于Python爬虫…

初级数据结构——栈

目录 前言一、栈的基本概念二、栈的实现方式三、栈的性能分析四、栈的应用场景五、栈的变体六、出栈入栈的动态图解七、代码模版八、总结结语 前言 数据结构栈&#xff08;Stack&#xff09;是一种线性的数据结构&#xff0c;它只允许在序列的一端&#xff08;称为栈顶&#x…

第八章 利用CSS制作导航栏

8.1 水平顶部导航栏 8.1.1 简单水平导航栏的设计与实现 1. 响应式设计 介绍&#xff1a; 响应式设计是指网页能够根据不同设备屏幕尺寸和分辨率自适应调整布局和样式&#xff0c;以确保在手机、平板和桌面等设备上都能提供良好的用户体验。 CSS实现&#xff1a; media (ma…

NoSQL数据库与关系型数据库的主要区别

NoSQL数据库与关系型数据库在多个方面存在显著区别&#xff0c;以下是对这些主要区别的详细描述&#xff1a; 一、数据存储模型 关系型数据库&#xff1a;使用表格形式存储数据&#xff0c;每个表格由行和列组成&#xff0c;行表示记录&#xff0c;列表示字段。数据之间的关系…