Spring Boot(8)深入理解 @Autowired 注解:使用场景与实战示例
搞个引言
在 Spring 框架的开发中,依赖注入(Dependency Injection,简称 DI)是它的一个核心特性,它能够让代码更加模块化、可测试,并且易于维护。而 @Autowired 注解作为 Spring 实现依赖注入的关键工具,给咱们开发者提供了极大的便利。本文将通过具体的示例详细介绍 @Autowired 注解的多种使用场景,帮助你更好地掌握这一重要注解~
一、构造函数注入
1.1 基本原理
当一个类依赖于其他 Bean 时,使用 @Autowired 注解在构造函数上进行依赖注入是一种推荐的方式。这种方式能保证对象在创建时其依赖项就已经被正确初始化,符合依赖项不变性原则。也就是说,对象一旦创建完成,其依赖的 Bean 就不会再改变了。
1.2 示例代码
// 定义一个服务接口
interface UserService {void saveUser();
}// 实现服务接口
class UserServiceImpl implements UserService {@Overridepublic void saveUser() {System.out.println("User saved.");}
}// 定义一个控制器类,依赖 UserService
class UserController {private final UserService userService;// 使用 @Autowired 注解在构造函数上进行依赖注入@Autowiredpublic UserController(UserService userService) {this.userService = userService;}public void handleSaveUser() {userService.saveUser();}
}
1.3 代码解释
在上述代码中,UserController 类依赖于 UserService 接口的实现类。通过在构造函数上使用 @Autowired 注解,Spring 容器会自动查找 UserService 类型的 Bean,并将其注入到 UserController 的构造函数中。这样,在创建 UserController 对象时,userService 字段就已经被正确初始化,后续可以直接使用。
1.4 使用优势
- 依赖不可变:使用构造函数注入,一旦对象创建完成,其依赖的 Bean 就不会再改变,保证了对象状态的一致性。
- 便于单元测试:在进行单元测试时,可以方便地通过构造函数传入模拟对象,提高代码的可测试性。
二、Setter 方法注入
2.1 基本原理
除了构造函数注入,@Autowired 注解还可以用于 Setter 方法上。这种方式允许在对象创建后动态地注入依赖项,适用于一些依赖项可能会在对象生命周期内发生变化的场景。
2.2 示例代码
// 定义一个邮件服务接口
interface EmailService {void sendEmail(String message);
}// 实现邮件服务接口
class EmailServiceImpl implements EmailService {@Overridepublic void sendEmail(String message) {System.out.println("Sending email: " + message);}
}// 定义一个通知服务类,依赖 EmailService
class NotificationService {private EmailService emailService;// 使用 @Autowired 注解在 Setter 方法上进行依赖注入@Autowiredpublic void setEmailService(EmailService emailService) {this.emailService = emailService;}public void sendNotification(String message) {emailService.sendEmail(message);}
}
2.3 代码解释
在这个示例中,NotificationService 类依赖于 EmailService。通过在 setEmailService 方法上使用 @Autowired 注解,Spring 容器会自动查找 EmailService 类型的 Bean,并调用该 Setter 方法将其注入到 NotificationService 对象中。
2.4 使用优势
- 灵活性高:可以在对象创建后动态地改变依赖项,适应不同的业务需求。
- 部分依赖注入:当一个类有多个依赖项,但不是所有依赖项都需要在对象创建时立即注入时,使用 Setter 方法注入可以更灵活地管理依赖。
三、字段注入
3.1 基本原理
@Autowired 注解还可以直接用于类的字段上,这是一种最简单的依赖注入方式。Spring 容器会自动查找匹配类型的 Bean,并将其注入到相应的字段中。
3.2 示例代码
// 定义一个日志服务接口
interface LogService {void log(String message);
}// 实现日志服务接口
class LogServiceImpl implements LogService {@Overridepublic void log(String message) {System.out.println("Logging: " + message);}
}// 定义一个业务服务类,依赖 LogService
class BusinessService {// 使用 @Autowired 注解在字段上进行依赖注入@Autowiredprivate LogService logService;public void doBusiness() {logService.log("Business operation started.");// 业务逻辑代码logService.log("Business operation completed.");}
}
3.3 代码解释
在 BusinessService 类中,logService 字段使用了 @Autowired 注解。Spring 容器会自动查找 LogService 类型的 Bean,并将其注入到该字段中。这样,在 doBusiness 方法中就可以直接使用 logService 进行日志记录。
3.4 使用优势
- 代码简洁:无需编写构造函数或 Setter 方法,代码更加简洁明了。
3.5 使用注意事项
- 不利于单元测试:由于字段注入是通过反射实现的,在进行单元测试时,难以直接注入模拟对象,降低了代码的可测试性。
- 依赖不明确:字段注入隐藏了类的依赖关系,不利于代码的维护和理解。
四、数组和集合注入
4.1 基本原理
@Autowired 注解不仅可以注入单个 Bean,还可以注入数组或集合类型的 Bean。Spring 容器会自动查找所有匹配类型的 Bean,并将它们注入到相应的数组或集合中。
4.2 示例代码
// 定义一个消息处理器接口
interface MessageHandler {void handleMessage(String message);
}// 实现消息处理器接口
class EmailMessageHandler implements MessageHandler {@Overridepublic void handleMessage(String message) {System.out.println("Handling email message: " + message);}
}class SmsMessageHandler implements MessageHandler {@Overridepublic void handleMessage(String message) {System.out.println("Handling SMS message: " + message);}
}// 定义一个消息分发服务类,依赖多个 MessageHandler
class MessageDispatcherService {// 使用 @Autowired 注解注入 MessageHandler 数组@Autowiredprivate MessageHandler[] messageHandlers;public void dispatchMessage(String message) {for (MessageHandler handler : messageHandlers) {handler.handleMessage(message);}}
}
3.3 代码解释
在 MessageDispatcherService 类中,messageHandlers 字段是一个 MessageHandler 数组,使用 @Autowired 注解进行注入。Spring 容器会自动查找所有实现了 MessageHandler 接口的 Bean,并将它们注入到该数组中。在 dispatchMessage 方法中,可以遍历数组并调用每个 MessageHandler 的 handleMessage 方法。
3.4 使用优势
- 方便管理多个同类型 Bean:当一个类需要依赖多个同类型的 Bean 时,使用数组或集合注入可以方便地管理这些 Bean。
五、总结
@Autowired 注解为 Spring 框架中的依赖注入提供了多种灵活的方式,包括构造函数注入、Setter 方法注入、字段注入以及数组和集合注入。在实际开发中,应根据具体的业务场景和需求选择合适的注入方式。构造函数注入适用于依赖项不变的场景,能提高代码的可测试性;Setter 方法注入提供了更高的灵活性,适用于依赖项可能动态变化的情况;字段注入虽然代码简洁,但不利于单元测试和代码维护;数组和集合注入则方便管理多个同类型的 Bean。通过合理使用 @Autowired 注解,可以让代码更加模块化、可维护和易于测试。
✍结尾
🀙🀚🀛🀜🀝🀞🀟🀠🀡🀐🀑🀒🀓🀔🀕🀖🀘🀗🀏🀎🀍🀌🀋🀊🀉🀈🀇🀆🀅🀃🀂🀁🀀🀄︎🀢🀣🀥🀤🀦🀧🀨🀩🀪
📘 妹妹听后点了点头,脸上露出了满意的笑容。她轻声说道:“原来如此,谢谢你,鸽鸽。看来我不仅要多读书,还要多动手实践,提升自己才行。”
看着她那充满求知欲的眼神,我不禁感叹,学习之路虽然充满挑战,但有这样一位美丽聪慧的伙伴相伴,一切都变得格外有意义。快去和妹妹一起实践一下吧!

📘相关阅读⚡⚡
笔者 綦枫Maple 的其他作品,欢迎点击查阅哦~:
📚Jmeter性能测试大全:Jmeter性能测试大全系列教程!持续更新中!
📚UI自动化测试系列: Selenium+Java自动化测试系列教程❤
📚移动端自动化测试系列:Appium自动化测试系列教程
📚Postman系列:Postman高级使用技巧系列
👨🎓作者:綦枫Maple
🚀博客:CSDN、掘金等
🚀CSDN技术社区:https://bbs.csdn.net/forums/testbean
🚀网易云音乐:https://y.music.163.com/m/user?id=316706413
🚫特别声明:原创不易,转载请附上原文出处链接和本文声明,谢谢配合。
🙏版权声明:文章里可能部分文字或者图片来源于互联网或者百度百科,如有侵权请联系处理。
🀐其他:若有兴趣,可以加文章结尾的Q群,一起探讨学习哦~
相关文章:
Spring Boot(8)深入理解 @Autowired 注解:使用场景与实战示例
搞个引言 在 Spring 框架的开发中,依赖注入(Dependency Injection,简称 DI)是它的一个核心特性,它能够让代码更加模块化、可测试,并且易于维护。而 Autowired 注解作为 Spring 实现依赖注入的关键工具&…...
【linux】在 Linux 服务器上部署 DeepSeek-r1:70b 并通过 Windows 远程可视化使用
【linux】在 Linux 服务器上部署 DeepSeek-r1:70b 并通过 Windows 远程可视化使用 【承接商业广告,如需商业合作请+v17740568442】 文章目录 【linux】在 Linux 服务器上部署 DeepSeek-r1:70b 并通过 Windows 远程可视化使用个人配置详情一、安装ollama二、下载deepseek版本…...
【AI大模型】Ollama部署本地大模型DeepSeek-R1,交互界面Open-WebUI,RagFlow构建私有知识库
文章目录 DeepSeek介绍公司背景核心技术产品与服务应用场景优势与特点访问与体验各个DeepSeek-R系列模型的硬件需求和适用场景 Ollama主要特点优势应用场景安装和使用配置环境变量总结 安装open-webui下载和安装docker desktop配置镜像源安装open-webui运行和使用 RagFlow介绍主…...
Unity 命令行设置运行在指定的显卡上
设置运行在指定的显卡上 -force-device-index...
Visual Studio 使用 “Ctrl + /”键设置注释和取消注释
问题:在默认的Visual Studio中,选择单行代码后,按下Ctrl /键会将代码注释掉,但再次按下Ctrl /键时,会进行双重注释,这不是我们想要的。 实现效果:当按下Ctrl /键会将代码注释掉,…...
共用poetry和conda的方法
起因 基于开源项目继续开发,发现该项目使用poetry管理依赖,但本地开发及调试环境依赖conda且未安装原生python,不支持直接安装poetry,因此需要使用conda安装及使用poetry。操作系统:Ubuntu 什么是poetry 一项依赖于…...
教程:使用 Vue 3 和 arco 实现表格合并
1. 功能概述 本教程将介绍如何使用 Vue 3 和 arco 组件库实现表格合并功能。具体来说,我们会根据表格数据中的某个字段(如 type)对表格的某一列(如入库类型列)进行合并,同时将质检说明列合并为一列。 2. …...
Docker 常用命令基础详解(二)
四、容器操作命令 4.1 运行容器 使用docker run命令可以创建并运行一个容器,它就像是一个神奇的 “启动器”,让镜像中的应用程序在容器中运行起来。其基本语法为: docker run [OPTIONS] IMAGE [COMMAND] [ARG...] 其中,OPTIONS…...
uniapp - iconfont下载本地并且运用至项目上
1、项目中创建一个文件夹放置iconfont相关文件,例如src/assets/iconfont(名称自己定义) 2、在iconfont下载项目至本地 3、解压后把文件复制进1的文件夹中 4、修改src/assets/iconfont - iconfont.css里的font-face的src地址,修…...
【前端】自己从头实现一个gpt聊天页面
预览 最小化功能点 主界面:侧边栏会话历史、聊天窗口发送和断开。侧边栏:展示会话列表,每个会话包含多条聊天记录, 通过localstorage本地储存和恢复,会话需要重命名和删除。聊天框:区分一下发送者和回答者…...
数据结构——二叉树(2025.2.12)
目录 一、树 1.定义 (1)树的构成 (2)度 2.二叉树 (1)定义 (2)二叉树的遍历 (3)遍历特性 二、练习 1.二叉树 (1)创建二叉树…...
Vulhub靶机 ActiveMQ任意 文件写入(CVE-2016-3088)(渗透测试详解)
一、开启vulhub环境 docker-compose up -d 启动 docker ps 查看开放的端口 漏洞版本:ActiveMQ在5.14.0之前的版本(不包括5.14.0) 二、访问靶机IP 8161端口 默认账户密码都是admin 1、利用bp抓包,修改为PUT方法并在fileserver…...
跟着李沐老师学习深度学习(十一)
经典的卷积神经网络 在本次笔记中主要介绍一些经典的卷积神经网络模型,主要包含以下: LeNet:最早发布的卷积神经网络之一,目的是识别图像中的手写数字;AlexNet: 是第一个在大规模视觉竞赛中击败传统计算机…...
【微软- Entra ID】Microsoft Entra ID
Microsoft Entra ID是微软提供的基于云的身份和访问管理服务。Microsoft Entra ID是一个全面的解决方案,用于管理身份、执行访问策略以及在云和本地保护您的应用程序和数据。 目录 一、查看 Microsoft Entra ID 微软Entra租户 微软Entra模式 二、比较Microsoft Entra ID与…...
Halcon相机标定
1,前言。 相机的成像过程实质上是坐标系的转换。首先空间中的点由“世界坐标系”转换到“相机坐标系”,然后再将其投影到成像平面(图像物理坐标系),最后再将成像的平面上的数据转换为图像像素坐标系。但是由于透镜的制…...
Linux 配置 MySQL 定时自动备份到另一台服务器
Linux 配置 MySQL 定时自动备份到另一台服务器 前言1、配置服务器通信1.1:配置过程 2、编写自动备份sh脚本文件3:设置定时自动执行 前言 此方案可使一台服务器上的 MySQL 中的所有数据库每天 0 点自动转储为 .sql 文件,然后将文件同步到另一…...
《安富莱嵌入式周报》第350期:Google开源Pebble智能手表,开源模块化机器人平台,开源万用表,支持10GHz HRTIM的单片机,开源CNC控制器
周报汇总地址:嵌入式周报 - uCOS & uCGUI & emWin & embOS & TouchGFX & ThreadX - 硬汉嵌入式论坛 - Powered by Discuz! 视频版: https://www.bilibili.com/video/BV1YPKEeyEeM/ 《安富莱嵌入式周报》第350期:Google开…...
LabVIEW与小众设备集成
在LabVIEW开发中,当面临控制如布鲁克OPUS红外光谱仪这类小众专业设备的需求,而厂家虽然提供了配套软件,但由于系统中还需要控制其他设备且不能使用厂商的软件时,必须依赖特定方法通过LabVIEW实现设备的控制。开发过程中࿰…...
无人机之无线传输技术!
一、Lightbridge和OcuSync图传技术 Lightbridge技术:这是大疆自主研发的一种专用通信链路技术,使用单向图像数据传输,类似于电视广播塔的数据传输形式。它主要采用2.4GHz频段进行传输,并且可以实现几乎“零延时”的720p高清图像传…...
移远通信边缘计算模组成功运行DeepSeek模型,以领先的工程能力加速端侧AI落地
近日,国产大模型DeepSeek凭借其“开源开放、高效推理、端侧友好”的核心优势,迅速风靡全球。移远通信基于边缘计算模组SG885G,已成功实现DeepSeek模型的稳定运行,并完成了针对性微调。 目前,该模型正在多款智能终端上进…...
rust学习一、入门之搭建简单开发环境
1、搭建开发环境(windows11) a.登录官网 一看就明白,此处略。 b.安装rustup 一看就明白,此处略。 c.安装 cargo script 或者 rust-script script cargo install cargo-script 完成后 注意:时间有一点点久。 测试 cargo s…...
FANUC机器人示教器中如何显示或关闭寄存器或IO的注释信息?
FANUC机器人示教器中如何显示或关闭寄存器或IO的注释信息? 如下图所示,我们打开一个子程序,可以看到程序中的寄存器和IO是显示注释信息的, 如果想关闭注释显示的话,怎么设置? 如下图所示,按下下一页的箭头(NEXT键), 如下图所示,点击“编辑”,在弹出的窗口中,选择“…...
在SpringBoot项目中有k8s配置,但报错
如下报错一般是你没有将k8s的config拷贝到项目里,你可以将k8s主节点的config拷贝一下到项目中。 2025-02-13 09:27:21.873 ERROR 1671 --- [.models.V1Pod-1] i.k.c.informer.cache.ReflectorRunnable : class io.kubernetes.client.openapi.models.V1Pod#Reflec…...
在springboot加vue项目中加入图形验证码
后端 首先先要创建一个CaptchaController的类,可以在下面的代码中看到 在getCaptcha的方法里面写好了生成随机的4位小写字母或数字的验证码,然后通过BufferedImage类变为图片,顺便加上了干扰线。之后把图片转为Base64编码方便传给前端 为了…...
23. AI-大语言模型
文章目录 前言一、LLM1. 简介2. 工作原理和结构3. 应用场景4. 最新研究进展5. 比较 二、Transformer架构1. 简介2. 基本原理和结构3. 应用场景4. 最新进展 三、开源1. 开源概念2. 开源模式3. 模型权重 四、再谈DeepSeek 前言 AI 一、LLM LLM(Large Language Mod…...
蓝桥杯备赛笔记(二)
这里的笔记是关于蓝桥杯关键知识点的记录,有别于基础语法,很多内容只要求会用就行,无需深入掌握。 文章目录 前言一、时间复杂度1.1 时间复杂度⭐1.2 空间复杂度1.3 分析技巧 二、枚举2.1 枚举算法介绍2.2 解空间的类型2.3 循环枚举解空间 三…...
MATLAB中的APPdesigner绘制多图问题解析?与逻辑值转成十进制
在matlab APPdesigner中绘图可以用UIAxes组件进行绘图,但是当想多张图时,只能提前绘制图像区域不方便。下面是几种办法: 为了操作可以添加Panl组件,方便操作。 1、当是要求的几个图像大小都是相同时刻采用函数: til…...
Spring Cloud-Sentinel
Sentinel服务熔断与限流 Sentinel 是面向分布式、多语言异构化服务架构的流量治理组件,主要以流量为切入点,从流量控制、流量路由、熔断降级、系统自适应保护等多个维度来帮助用户保障微服务的稳定性。 官网地址:home | Sentinelhttps://sen…...
Java中使用EasyExcel
Java中使用EasyExcel 文章目录 Java中使用EasyExcel一:EasyExcel介绍1.1、核心函数导入数据导出数据 1.2、项目实际应用导入数据导出数据 1.3、相关注解ExcelProperty作用示例 二:EasyExcel使用2.1、导入功能2.2、导出功能 三:EasyExcel完整代…...
Linux中退出vi编辑器的命令
在Linux中退出vi编辑器的命令有以下几种: 保存并退出:在命令模式下,按下Esc键退出插入模式,然后输入:wq或:x,按下回车键即可保存修改并退出vi编辑器。 不保存退出:在命令模式下,按…...
