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.rhkb.cn/news/450580.html

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

相关文章

常用代码整理

字符串操作相关函数的实现 gets puts strlen strcat strncat strcpy strncpy strcmp strncmp memcpy 内存大小端判断 类型强制转换 联合 排序 选择排序 冒泡排序 插入排序 快速排序 先选一个基准值,通过双指针扫描并交换元素将数组划分为两部分,左…

6.计算机网络_UDP

UDP的主要特点: 无连接,发送数据之前不需要建立连接。不保证可靠交付。面向报文。应用层给UDP报文后,UDP并不会抽象为一个一个的字节,而是整个报文一起发送。没有拥塞控制。网络拥堵时,发送端并不会降低发送速率。可以…

gitee建立/取消关联仓库

目录 一、常用指令总结 二、建立关联具体操作 三、取消关联具体操作 一、常用指令总结 首先要选中要关联的文件,右击,选择Git Bash Here。 git remote -v //查看自己的文件有几个关联的仓库git init //初始化文件夹为git可远程建立链接的文件夹…

transformer的基础知识

transformer的基础知识 transformer网络结构图 seq2seq 一般Seq2seq会分成两部分:Encoder、Decoder。 Encoder Transformer 中的 Encoder 就是用的 Self-attention。 encoder的内部结构 补充:block的内部结构主要由self-attention和全连接神经网络所构成。 在原来的论…

TSmaster CAN的E2E检验配置

文章目录 一. 自定义E2E校验算法1. 导入DBC文件2. 模拟报文发送3. 自定义E2E算法 问题:C代码编辑器中 数据库头文件为空问题:C代码编辑器中 程序启动和暂停按钮为灰色 一. 自定义E2E校验算法 1. 导入DBC文件 点击载入CAN数据库,在弹窗中选择…

添加卡巴斯基杀毒软件(KES)的更新源

最近不知道怎么了,家里的电脑卡巴斯基(KES)怎么更新都更新不了,在网上找到了几个卡巴斯基的服务器: 添加步骤: 1.双击右下角的卡巴斯基图标。 2.依次按如下图示添加: 以下这步是最关键的,一定要…

HDU Ignatius‘s puzzle

题目大意&#xff1a;f&#xff08;x&#xff09;5*x^1313*x^5k*a*x&#xff0c;输入一个无负整数 k&#xff08;k<10000&#xff09;&#xff0c;要找到最小的非负整数 a&#xff0c;将任意整数 x &#xff0c;65|f&#xff08;x&#xff09;&#xff0c;如果不存在该 a&am…

矩阵AB=0

矩阵AB0的性质 一、二的证明 这里还有一种说法 三、四的证明 详情请跳转五

linux环境下的程序设计与git操作

目录 前言&#xff1a; 进度条小程序&#xff1a; 先介绍几个背景知识 代码实现 Git操作 总结 其他指令 前言&#xff1a; 本文将重点介绍1. linux下的程序设计&#xff0c;并使用linux下的几个函数接口。实现一个简单的小程序 2.本着开源精神&#xff0c;进行git操作。…

数据同步工具Sqoop原理及场景优化

目录 0 数据同步策略 1 数据同步工具 ​编辑 2 Sqoop同步数据原理分析 2.1 原理分析 2.2 Sqoop基本使用分析 3 切片逻辑 3.1 MR切片逻辑 3.2 Hive CombineInputformat切片逻辑 3.3 实验1:Map任务并行度分析1 3.4 实验2: Map任务并行度分析2 3.5 实验3:Map任务并行…

SDIO - DWC MSHC 电压切换和频率切换

背景 我们的sdio访问sd card过去一直跑在低频上&#xff0c;HS50M。前段时间给eMMc添加了HS200模式&#xff0c;eMMc的总线模式定义是这样的&#xff1a; 可以看到1.8V的IO 电压可以支持所有模式&#xff0c;我们过去的芯片&#xff0c;由硬件部门放到evb上&#xff0c;其IO …

【学习笔记】什么是MongoDB

文章目录 MongoDB 简介体系结构数据模型MongoDB 的特点 MongoDB 简介 学习一个东西就跟认识一个人一样&#xff0c;下面有情MongoDB来做个自我介绍 大家好&#xff0c;俺是MongoDB&#xff0c;是一个开源、高性能、无模式的文档型数据库&#xff0c;当初的设计俺就是用于简化开…

Redis-03 持久化(RDB, AOF,混合持久化)及原理

1&#xff0c;持久化 Redis的持久化是必须的&#xff0c;当Redis服务宕机后&#xff0c;如果没有持久化&#xff0c;重启服务后redis中的数据都将丢失&#xff0c;所有的数据操作都将直连数据库&#xff0c;系统性能会大幅降低&#xff0c;所以在使用Redis做缓存服务时必须持久…

LabVIEW离心泵振动监控与诊断系统

利用LabVIEW结合数据采集与处理技术&#xff0c;构建了一套高效、低成本的振动监测与诊断系统&#xff0c;有效提升了测试精度与设备可靠性。 项目背景 在化工生产中&#xff0c;离心泵作为关键设备&#xff0c;其稳定运行对保障生产安全与效率至关重要。由于传统振动测试系统…

#数据结构(一)

线性表 两者都属于线性表线性表&#xff1a;逻辑结构------必连续      物理结构------不一定连续顺序表的物理结构 -----连续 &#xff0c;链表的物理结构 ----不连续顺序表的本质是数组&#xff0c;数组是一块地址连续的空间。而链表只是像细线一样&#xff0c;将不同地址…

LabVIEW提高开发效率技巧----VI继承与重载

在LabVIEW开发中&#xff0c;继承和重载是面向对象编程&#xff08;OOP&#xff09;中的重要概念。通过合理运用继承与重载&#xff0c;不仅能提高代码的复用性和灵活性&#xff0c;还能减少开发时间和维护成本。下面从多个角度介绍如何在LabVIEW中使用继承和重载&#xff0c;并…

萤石云服务支持云端视频AI自动剪辑生成

萤石视频云存储及媒体处理服务是围绕IoT设备云端存储场景下的音视频采集、媒体管理、视频剪辑和分发能力的一站式、专业云服务&#xff0c;并可面向广大开发者提供复杂设备存储场景下的完整技术方案。目前该服务新增了视频剪辑功能&#xff0c;支持将视频片段在云端进行裁剪并拼…

sentinel dashboard分布式改造落地设计实现解释(二)-分布式discovery组件

discovery discovery负责维护app/机器资料库&#xff0c;transport健康检测&#xff0c; transport上下线处理。discovery关键是分布式存储&#xff0c;后续研究一下raft&#xff0c;其复制&#xff0c;状态机&#xff0c;快照技术&#xff0c;但个人觉得&#xff0c;discover…

胤娲科技:AI短视频——创意无界,即梦启航

在这个快节奏的时代&#xff0c;你是否曾梦想过用几秒钟的短视频&#xff0c;捕捉生活中的每一个精彩瞬间&#xff1f;是否曾幻想过&#xff0c;即使没有专业的摄影和剪辑技能&#xff0c;也能创作出令人惊艳的作品&#xff1f; 现在&#xff0c;这一切都不再是遥不可及的梦想。…

基于光度学的小型视触觉传感器的开发

近年来&#xff0c;视觉触觉传感器&#xff08;VTS&#xff09;在机器人领域得到了广泛关注。传统的触觉传感器如压阻式、压电式和电容式触觉传感器在机器人感知方面有显著优势&#xff0c;但其分辨率相对较低。视触觉传感器使用相机获取触觉信息&#xff0c;能够提供高分辨率和…