【Spring】Spring DI(依赖注入)详解—集合类型的注入——List、Set、Map的配置与注入

一、引言

Spring依赖注入不仅能简化对象的创建和管理,还能使得代码更加灵活和可维护。尤其是在处理集合类型的依赖时,Spring的DI机制提供了更为灵活的方式来管理和注入多个依赖。

1.1 依赖注入的重要性

在大型应用中,类与类之间的关系往往是复杂的。例如,一个电商平台的订单服务可能依赖于多个支付方式、多个商品服务和多个用户服务。在这种情况下,手动管理这些依赖关系会导致代码冗长且难以维护。

使用Spring的依赖注入,我们可以轻松地将多个依赖注入到一个类中,而无需在代码中手动创建这些依赖。通过配置文件或注解,Spring容器能够自动管理这些依赖关系。

1.2 生活中的类比

可以将集合类型的注入类比于一个厨房中的厨具。想象一下,你的厨房里有多种烹饪工具(刀具、锅具、调料等),而你需要在烹饪时根据不同的需求选择不同的工具。依赖注入就像是一个厨师助手,他会根据你要做的菜品,自动为你准备好所需的所有工具,而你只需专注于烹饪本身。

二、Spring集合类型的依赖注入

Spring支持通过依赖注入将集合类型(如ListSetMap)注入到类中。这样,我们可以轻松地管理多个相同类型的依赖。以下是对每种集合类型的详细介绍。

2.1 List的注入

List是一种有序的集合,可以包含重复元素。我们可以将多个相同类型的bean注入到一个List中。

示例代码
  1. 定义接口和实现类

// PaymentMethod.java
public interface PaymentMethod {void pay();
}// CreditCardPayment.java
public class CreditCardPayment implements PaymentMethod {@Overridepublic void pay() {System.out.println("Payment made using Credit Card.");}
}// PayPalPayment.java
public class PayPalPayment implements PaymentMethod {@Overridepublic void pay() {System.out.println("Payment made using PayPal.");}
}
  1. 定义依赖类

// OrderService.java
import java.util.List;public class OrderService {private List<PaymentMethod> paymentMethods;// 使用setter方法注入Listpublic void setPaymentMethods(List<PaymentMethod> paymentMethods) {this.paymentMethods = paymentMethods;}public void processOrder() {System.out.println("Processing order...");for (PaymentMethod paymentMethod : paymentMethods) {paymentMethod.pay(); // 调用每种支付方式的pay方法}}
}
  1. Spring配置文件

<!-- applicationContext.xml -->
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd"><!-- 定义支付方式的bean --><bean id="creditCardPayment" class="CreditCardPayment" /><bean id="paypalPayment" class="PayPalPayment" /><!-- 定义OrderService bean,并注入List --><bean id="orderService" class="OrderService"><property name="paymentMethods"><list><ref bean="creditCardPayment" /><ref bean="paypalPayment" /></list></property></bean>
</beans>
  1. 启动Spring容器

// Main.java
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;public class Main {public static void main(String[] args) {ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");OrderService orderService = (OrderService) context.getBean("orderService");orderService.processOrder();}
}
运行结果
Processing order...
Payment made using Credit Card.
Payment made using PayPal.
2.2 Set的注入

Set是一种不允许重复元素的集合。我们可以将多个相同类型的bean注入到一个Set中,Spring会自动处理重复的元素。

示例代码
  1. 定义依赖类

// NotificationService.java
import java.util.Set;public class NotificationService {private Set<String> notifications;// 使用setter方法注入Setpublic void setNotifications(Set<String> notifications) {this.notifications = notifications;}public void sendNotifications() {System.out.println("Sending notifications:");for (String notification : notifications) {System.out.println(notification);}}
}
  1. Spring配置文件

<!-- applicationContext.xml -->
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd"><!-- 定义NotificationService bean,并注入Set --><bean id="notificationService" class="NotificationService"><property name="notifications"><set><value>Email Notification</value><value>SMS Notification</value><value>Push Notification</value></set></property></bean>
</beans>
  1. 启动Spring容器

// Main.java
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;public class Main {public static void main(String[] args) {ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");NotificationService notificationService = (NotificationService) context.getBean("notificationService");notificationService.sendNotifications();}
}
运行结果
Sending notifications:
Email Notification
SMS Notification
Push Notification
2.3 Map的注入

Map是一种键值对集合,可以存储多个元素,并通过键来访问对应的值。我们可以将多个相同类型的bean注入到一个Map中。

示例代码
  1. 定义依赖类

// UserService.java
import java.util.Map;public class UserService {private Map<String, String> users;// 使用setter方法注入Mappublic void setUsers(Map<String, String> users) {this.users = users;}public void printUsers() {System.out.println("User List:");for (Map.Entry<String, String> entry : users.entrySet()) {System.out.println("Username: " + entry.getKey() + ", Full Name: " + entry.getValue());}}
}
  1. Spring配置文件

<!-- applicationContext.xml -->
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd"><!-- 定义UserService bean,并注入Map --><bean id="userService" class="UserService"><property name="users"><map><entry key="john_doe" value="John Doe" /><entry key="jane_doe" value="Jane Doe" /></map></property></bean>
</beans>
  1. 启动Spring容器

// Main.java
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;public class Main {public static void main(String[] args) {ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");UserService userService = (UserService) context.getBean("userService");userService.printUsers();}
}
运行结果
User List:
Username: john_doe, Full Name: John Doe
Username: jane_doe, Full Name: Jane Doe

三、总结

通过上述示例,我们展示了如何使用Spring的依赖注入来管理集合类型的依赖(ListSetMap)。这种方式使得我们能够轻松地将多个相同类型的bean注入到一个类中,提升了代码的可读性和可维护性。

在实际应用中,集合类型的注入非常常见,尤其是在需要处理多个相同类型的服务、配置或数据时。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/66300.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

贵州省贵安新区地图+全域数据arcgis格式shp数据矢量路网地名+卫星影像底图下载后内容测评

贵州省贵安新区地图全域数据arcgis格式shp数据矢量路网地名卫星影像底图 贵安新区地图是一款基于ArcGIS格式的地理信息系统数据集&#xff0c;包含2022年3月更新的详尽矢量路网、地名信息以及卫星影像底图。这款数据集是针对贵安新区这一特定区域设计的&#xff0c;对于规划、…

30分钟学会css

CSS 基本语法 CSS&#xff08;Cascading Style Sheets&#xff09;是一种样式表语言&#xff0c;用于描述 HTML&#xff08;或 XML&#xff09;文档的呈现。它可以控制网页元素的颜色、字体、布局等外观样式&#xff0c;实现内容与表现的分离&#xff0c;让网页设计更加灵活和…

pycharm完成git项目的拉取及修改,并保存为自己的项目,以cosyvoice为例

1.新建一个项目&#xff0c;如图 等待几分钟。因为还要虚拟环境的建立等。 2.克隆项目源码及提前准备&#xff08;备&#xff09; a.git的路径。 b.githube相关设置 左角。查看。 在对话框中&#xff0c;填写要摘取的仓库&#xff0c;提示非空目录。我给加了一个main 完成后&a…

Appium(一)--- 环境搭建

一、Android自动化环境搭建 1、JDK 必须1.8及以上(1) 安装&#xff1a;默认安装(2) 环境变量配置新建JAVA_HOME:安装路径新建CLASSPath%JAVA_HOME%\lib\dt.jar;%JAVA_HOME%\lib\tools.jar在path中增加&#xff1a;%JAVA_HOME%\bin;%JAVA_HOME%\jre\bin&#xff1b;(3) 验证…

C05S17-Redis数据库架设

一、Redis 1. Redis概述 Redis数据库属于NoSQL&#xff0c;是非关系型数据库&#xff0c;除主流的关系型数据库外&#xff0c;都认为是非关系型数据库。 非关系型数据库也有库&#xff0c;但是是系统自带的&#xff0c;不用创建、也不能创建。也无需建表&#xff0c;直接在系…

Spark是什么?Flink和Spark区别

Spark是什么&#xff1f;Flink和Spark区别 一、Spark二、Spark和Flink区别三、总结 一、Spark Apache Spark 是一个开源的大数据处理框架&#xff0c;主要用于大规模数据处理和分析。它支持多种数据处理模式&#xff0c;包括批处理、流处理、SQL 查询、机器学习和图处理等。 核…

Ant Design中Flex布局、Grid布局和Layout布局详解

好的&#xff0c;我们来更详细地探讨 Ant Design 中的 Flex布局、Grid布局 和 Layout布局 的特点、用法、适用场景&#xff0c;以及如何灵活运用它们来构建页面。下面将从各个方面进行更深入的分析&#xff0c;并提供具体的实例。 VueFlex布局实现响应式布局 1. Flex布局 概念…

Redis两种主要的持久化方式是什么?

Redis支持两种主要的持久化方式&#xff0c;它们分别是RDB&#xff08;Redis Database Snapshotting&#xff09;和AOF&#xff08;Append Only File&#xff09;。以下是这两种持久化方式的详细介绍&#xff1a; 一、RDB&#xff08;Redis Database Snapshotting&#xff09; …

flink cdc oceanbase(binlog模式)

接上文&#xff1a;一文说清flink从编码到部署上线 环境&#xff1a;①操作系统&#xff1a;阿里龙蜥 7.9&#xff08;平替CentOS7.9&#xff09;&#xff1b;②CPU&#xff1a;x86&#xff1b;③用户&#xff1a;root。 预研初衷&#xff1a;现在很多项目有国产化的要求&#…

C++文件流 例题

问题&#xff1a; 设计一个留言类&#xff0c;实现以下的功能&#xff1a; 1) 程序第一次运行时&#xff0c;建立一个 message.txt 文本文件&#xff0c;并把用户输入的信息存入该文件&#xff1b; 2) 以后每次运行时&#xff0c;都先读取该文件的内容并显示给用户&#xff…

exoplayer的使用-7,手势优化

之前的手势,虽然勉强实现了效果,但有一些问题. 手按着,会有抖动,这样就不断触发进度亮度这些. 第一次按下,然后拖动,产生的变化太大,严重不符合预期. touch在一个方法里面,从代码的角度看,不便于维护. Gesture手势类都给我们处理好了,双击,点击,滚动这些.所以打算用这个优化…

遮挡半透明效果

1、遮挡半透明效果是什么 在游戏开发中&#xff0c;遮挡半透明效果就是物体被挡住的部分&#xff0c;也能呈现出一种半透明效果而被看到&#xff08;具体效果可以自定义&#xff09;比如 当角色在建筑物之间穿行时&#xff0c;被遮挡部分能够呈现出半透明效果而被我们看到。遮…

大模型高效推理综述

大模型高效推理综述 1 Introduction2 Preliminaries2.1 transformer架构的LLM2.2 大模型推理过程2.3 推理效率分析 3 TAXONOMY(分类)4.数据级别优化4.1输入压缩4.1.1 提示词裁剪&#xff08;prompt pruning&#xff09;4.1.2 提示词总结&#xff08;prompt summary&#xff09;…

计算机网络--UDP和TCP课后习题

【5-05】 试举例说明有些应用程序愿意采用不可靠的UDP, 而不愿意采用可靠的TCP。 解答&#xff1a; 这可能有以下几种情况。 首先&#xff0c;在互联网上传输实时数据的分组时&#xff0c;有可能会出现差错甚至丢失。如果利用 TCP 协议对这些出错或丢失的分组进行重传&…

http://noi.openjudge.cn/_3.9数据结构之C++STL_1806:词典

题目 1806:词典 总时间限制: 3000ms 内存限制: 65536kB 描述 你旅游到了一个国外的城市。那里的人们说的外国语言你不能理解。不过幸运的是&#xff0c;你有一本词典可以帮助你。 输入 首先输入一个词典&#xff0c;词典中包含不超过100000个词条&#xff0c;每个词条占据一行…

深入探索:将 Elasticsearch 与 Ruby 工具结合使用

深入探索&#xff1a;将 Elasticsearch 与 Ruby 工具结合使用 一、背景介绍 1. Elasticsearch 与 Ruby 的结合背景 在现代软件开发中&#xff0c;Elasticsearch 作为一个基于 Lucene 的搜索引擎&#xff0c;以其分布式、可扩展、实时搜索等特点而广受欢迎。Ruby&#xff0c;…

模型分割的联邦微调与专家 MOE结合

基于模型分割的联邦微调 在基于模型分割的联邦微调中,要实现模型分割且不影响大模型整体效果,可从以下方面着手: 依据功能和数据特性分割:分析模型的功能结构以及不同部分对数据的依赖程度。例如,在自然语言处理的大模型中,可将词嵌入层、语法分析层、语义理解层等按功能…

MyBatis 与 MyBatis-Plus 的区别

MyBatis 和 MyBatis-Plus 都是用于简化 Java 应用程序与数据库交互的持久层框架&#xff0c;但它们在功能、易用性和性能优化方面存在显著差异。下面将详细介绍两者之间的区别&#xff0c;并通过具体的代码示例进行对比。 概述 MyBatis&#xff1a;作为一款经典的持久层框架&a…

Go语言的基础知识

1, Go 语言介绍 Go 即 Golang,是 Google公司2009年11月正式对外公开的一门编程语言。 根据 Go 语言开发者自述&#xff0c;近10多年&#xff0c;从单机时代的C语言到现在互联网时代的Java,都没有令人满意的开发语言&#xff0c;而C往往给人的感觉是&#xff0c;花了100%的经历…

【UE5 C++课程系列笔记】20——共享指针的简单使用

目录 概念 创建共享指针示例 重设共享指针 共享指针内容转移 共享指针和共享引用的转换 判断共享指针的相等性 共享指针访问成员函数 自定义删除器 概念 共享指针&#xff08;主要以 TSharedPtr 为例&#xff09;&#xff0c;TSharedPtr 基于引用计数机制来工作&#x…