Spring 的依赖注入的最常见方式

在这里插入图片描述

在 Spring 中,依赖注入的方式有多种选择。下面我们来逐一分析它们的特点、适用场景和注意事项:


1. 构造函数注入

构造函数注入要求在对象创建时提供所有依赖。这种方式确保依赖在对象创建后不可变,特别适合必须强制存在的依赖。所有依赖在对象实例化时即被注入,保证了依赖的一致性。

代码示例:
public class Car {private final Engine engine;public Car(Engine engine) {this.engine = engine;}
}
优点:
  • 确保依赖不可变,提升代码稳定性。
  • 更符合单一职责原则,有利于单元测试,因为构造函数明确列出了依赖项。
缺点:
  • 当依赖数量过多时,构造函数会显得过于复杂。

2. Setter 注入

Setter 注入允许在对象实例化后进行依赖的设置。相比构造函数注入,它更灵活,允许可选依赖。

代码示例:
public class Car {private Engine engine;public void setEngine(Engine engine) {this.engine = engine;}
}
优点:
  • 更加灵活,允许在对象创建之后再注入依赖。
  • 可以处理部分依赖可能为空的情况,适合有默认依赖的场景。
缺点:
  • 可能导致对象在使用前未完成依赖的设置,增加了潜在风险。

3. 字段注入

字段注入是通过 @Autowired 直接在属性上进行注入,Spring 会自动完成依赖的注入。这种方式简化了代码,但增加了依赖管理的复杂性。

代码示例:
public class Car {@Autowiredprivate Engine engine;
}
优点:
  • 代码简洁,不需要编写构造函数或 setter 方法。
  • 非常适合简单项目或快速开发场景。
缺点:
  • 依赖隐式注入,不易发现未初始化的属性。
  • 对单元测试不友好,需要使用反射进行依赖注入,增加测试复杂度。

4. 接口注入

接口注入通过定义特定接口,使实现类实现依赖的注入。这种方式在 Spring 项目中较少使用,但在一些严格控制的依赖关系中非常有效。

代码示例:
public interface EngineAware {void setEngine(Engine engine);
}public class Car implements EngineAware {private Engine engine;@Overridepublic void setEngine(Engine engine) {this.engine = engine;}
}
优点:
  • 清晰的依赖关系,强制依赖约束。
  • 更加灵活,能够在运行时动态注入依赖。
缺点:
  • 增加了接口的复杂性,通常不常用。

5. 工厂方法注入

通过 Spring 的 @Bean 注解,可以在工厂方法中生成 Bean,并进行复杂的依赖注入处理,适用于需要自定义创建逻辑的场景。

代码示例:
@Bean
public Car car() {return new Car(engine());
}@Bean
public Engine engine() {return new Engine();
}
优点:
  • 更灵活,允许复杂依赖的创建和配置。
  • 适合处理多步骤初始化的复杂依赖。
缺点:
  • 代码较为复杂,适合高级场景,不适合简单项目。

6. @Primary@Qualifier 注解

当有多个相同类型的 Bean 时,Spring 提供了 @Primary@Qualifier 注解来决定注入哪个 Bean。@Primary 标记默认注入的 Bean,@Qualifier 用来指定具体的 Bean。

代码示例:
@Component
@Qualifier("dieselEngine")
public class DieselEngine implements Engine {}@Component
@Primary
public class ElectricEngine implements Engine {}@Autowired
@Qualifier("dieselEngine")
private Engine engine;
优点:
  • 能精确选择 Bean,特别是在有多个相同类型的 Bean 时。
  • 提供了更加明确的控制,避免错误的 Bean 注入。
缺点:
  • 增加了配置的复杂性,适合有多个候选 Bean 的项目。

7. 环境配置条件注入

通过 @Conditional 注解,Spring 可以根据不同的条件注入依赖。例如,根据不同的环境配置文件(如 application-dev.ymlapplication-prod.yml),来决定注入哪个 Bean。

代码示例:
@ConditionalOnProperty(name = "app.env", havingValue = "dev")
@Bean
public DataSource devDataSource() {return new HikariDataSource();
}@ConditionalOnProperty(name = "app.env", havingValue = "prod")
@Bean
public DataSource prodDataSource() {return new DruidDataSource();
}
优点:
  • 允许根据环境动态注入 Bean,适合大型应用的多环境部署。
  • 减少了不必要的 Bean 加载,提升了性能。
缺点:
  • 需要依赖配置文件,增加了应用的复杂度。

依赖注入方式的对比

特性构造函数注入Setter 注入字段注入接口注入工厂方法注入@Primary@Qualifier环境配置注入
依赖注入时机对象创建时对象创建后框架自动完成接口回调实现工厂方法调用明确指定注入 Bean动态条件
代码简洁性较为复杂中等最简洁较复杂较复杂中等中等
灵活性较为固定灵活灵活灵活非常灵活灵活高度灵活
可维护性中等较低中等
测试友好性中等中等

结论

Spring 提供了多种依赖注入方式,每种方式都有其适用场景。构造函数注入最为稳健,但当需要灵活性时,Setter 注入和字段注入更为适合。工厂方法和条件注入适合更复杂的场景,而 @Qualifier@Primary 则用于处理多实现 Bean。根据项目需求选择合适的注入方式,才能在保持代码清晰的同时,提升可维护性和可扩展性。

在这里插入图片描述

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

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

相关文章

JavaWeb 22.Node.js_简介和安装

有时候,后退原来是向前 —— 24.10.7 一、什么是Node.js Node.js 是一个于 Chrome V8 的 JavaScript 运行时环境,可以使 JavaScript 运行在服务器端。使用 Node.js,可以方便地开发服务器端应用程序,如 Web 应用、API、后端服务&a…

Python 工具库每日推荐 【FastAPI】

文章目录 引言Web 框架的重要性今日推荐:FastAPI Web 框架主要功能:使用场景:安装与配置快速上手示例代码代码解释实际应用案例案例:构建一个简单的博客 API案例分析高级特性依赖注入系统后台任务扩展阅读与资源优缺点分析优点:缺点:总结【 已更新完 TypeScript 设计模式…

Transformer图解以及相关的概念

前言 transformer是目前NLP甚至是整个深度学习领域不能不提到的框架,同时大部分LLM也是使用其进行训练生成模型,所以transformer几乎是目前每一个机器人开发者或者人工智能开发者不能越过的一个框架。接下来本文将从顶层往下去一步步掀开transformer的面…

asp.net Core 自定义中间件

内联中间件 中间件转移到类中 推荐中间件通过IApplicationBuilder 公开中间件 使用扩展方法 调用中间件 含有依赖项的 》》》中间件 参考资料

中企通信赋能中信戴卡入选工信部颁发的2023年工业互联网试点示范名单

2024年10月17日,北京-随着工业互联网的迅猛发展,网络安全已成为国家关注的重点议题之一。日前,工业和信息化部(工信部)公布了2023年工业互联网试点示范名单,中企网络通信技术有限公司(简称“中企…

读数据工程之道:设计和构建健壮的数据系统12开源软件

1. 开源软件 1.1. 开源软件(Open Source Software,OSS)是一种软件发行模式,在这种模式下,软件和底层代码库通常在特定的许可条款下可供普遍开发者使用 1.2. 社区管理的开源软件 1.2.1. 大部分开源软件项目…

【Qt】信号和槽——信号和槽的概念、信号和槽的使用、信号和槽的优缺点、自定义信号和槽、信号和槽的断开

文章目录 Qt1. 信号和槽的概念2. 信号和槽的使用3. 信号和槽的优缺点4. 自定义信号和槽5. 信号和槽的断开 Qt 1. 信号和槽的概念 信号是什么: 在Linux中,我们知道信号是一种异步的事件通知机制,用于通知进程某个事件已经发生。它是进程间通信…

MOE论文详解(4)-GLaM

2022年google在GShard之后发表另一篇跟MoE相关的paper, 论文名为GLaM (Generalist Language Model), 最大的GLaM模型有1.2 trillion参数, 比GPT-3大7倍, 但成本只有GPT-3的1/3, 同时效果也超过GPT-3. 以下是两者的对比: 跟之前模型对比如下, 跟GShard和Switch-C相比, GLaM是第一…

opcode从零开始

opcode从零开始 参考资料: Intel 64 and IA-32 ArchitecturesSoftware Developer’s Manual Combined Volumes: 1, 2A, 2B, 2C, 2D, 3A, 3B, 3C, 3D, and 4() Intel64和IA-32架构软件开发人员手册组合卷:1,2a, 2B, 2C, 2D, 3A, 3B, 3C, 3D,和4 罗聪–c…

wordart.top - 轻松创建令人惊叹的文字云!

轻松创建令人惊叹的文字云/词云图!适合营销人员、教育工作者、数据爱好者、创意人员、商务人士、活动策划者和社交媒体专家等多种用户群体。支持海量模版库、自定义模板、文本快速提取、精准关键字调整、词云Gif动图制作、词云视频制作、图片一键分享及数据轻松导入…

网盘如何拉新方法教程

网盘拉新是指通过各种推广方式吸引新用户注册和使用网盘服务的过程。以下是对网盘拉新的详细解释: 一、网盘拉新的背景与意义 背景:随着互联网的发展,网盘作为一种基于云计算技术的存储服务,因其便捷性和高效性而备受欢迎。为了…

Linux debian 系桌面系统安装软件方式介绍

debian 系软件的安装方式多种多样,但对于不想花太多时间配置各种环境和依赖的用户来说,建议直接使用“新立得包管理器”安装,既方便又直观。 本文将以常用软件为例,介绍常用的几种软件安装方式。 1. 使用新立得包管理器安装&…

数据字典是什么?和数据库、数据仓库有什么关系?

一、数据字典的定义及作用 数据字典是一种对数据的定义和描述的集合,它包含了数据的名称、类型、长度、取值范围、业务含义、数据来源等详细信息。 数据字典的主要作用如下: 1. 对于数据开发者来说,数据字典包含了关于数据结构和内容的清晰…

15分钟学Go 第4天:Go的基本语法

第4天:基本语法 在这一部分,将讨论Go语言的基本语法,了解其程序结构和基础语句。这将为我们后续的学习打下坚实的基础。 1. Go语言程序结构 Go语言程序的结构相对简单,主要包括: 包声明导入语句函数语句 1.1 包声…

react+video:限制快进、倍速、画中画

实现代码&#xff1a; <video ref{videoRef} src{videoUrl} className{style.video} controls onRateChange{rateChange} onPlay{playVideo} onPause{pauseVideo} onTimeUpdate{timeUpdate} disablePictureInPicture playsInline poster{poster} controlsList"nodownl…

卸载Python

1、查看安装框架位置并删除 Sudo rm -rf /Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.8 2、查看应用并删除 在 /Applications/Python 3.x 看是否存在&#xff0c;如果存在并删除。 3、删除软连接 ls -l /usr/bin/py* 或 ls -…

MATLAB电车(宝马 i3)卸载电池再利用电气模型分析

&#x1f3af;要点 特性测试评估卸载电池性能以及不同温度下电池容量和电阻。使用两种电气模型评估和模拟卸载电池可利用性能。从宝马 i3模块中提取三星三元锂方形电池作为评估电池&#xff1a;容量测量、电阻测量&#xff0c;对比新电池性能。使用的等效电路模型以及用于校准…

群晖前面加了雷池社区版,安装失败,然后无法识别出用户真实访问IP

有nas的相信对公网都不模式&#xff0c;在现在基础上传带宽能有100兆的时代&#xff0c;有公网代表着家里有一个小服务器&#xff0c;像百度网盘&#xff0c;优酷这种在线服务都能部署为私有化服务。但现在运营商几乎不可能提供公网ip&#xff0c;要么自己买个云服务器做内网穿…

MacOS RocketMQ安装

MacOS RocketMQ安装 文章目录 MacOS RocketMQ安装一、下载二、安装修改JVM参数启动关闭测试关闭测试测试收发消息运行自带的生产者测试类运行自带的消费者测试类参考博客&#xff1a;https://blog.csdn.net/zhiyikeji/article/details/140911649 一、下载 打开官网&#xff0c;…

ListView的Items绑定和comboBox和CheckBox组合使用实现复选框的功能

为 ListView 控件的内容指定视图模式的方法&#xff0c;参考官方文档。 ComboBox 样式和模板 案例说明&#xff1a;通过checkBox和ComboBox的组合方式实现下拉窗口的多选方式&#xff0c;同时说明了ListView中Items项目的两种绑定方式. 示例&#xff1a; 设计样式 Xaml代码…