当前位置: 首页 > news >正文

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 方法中,可以遍历数组并调用每个 MessageHandlerhandleMessage 方法。

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 实现依赖注入的关键工具&…...

UE_C++ —— Structs

目录 一,实现一个UStruct 二,Struct Specifiers 三,最佳做法与技巧 结构体(Struct)是一种帮助组织和操作相关属性的数据结构;在引擎中,结构体会被引擎反射系统识别为 UStruct,但不…...

ArcGISPro 新建shp+数据结构

import arcpy# 设置工作空间和 Shapefile 存放路径 shp_path r"C:\path\to\your\folder\PolygonZY.shp" # Shapefile 存放路径 fields [("CHBH", "TEXT", 20),("ZCMC", "TEXT", 100),("ZCLX", "TEXT"…...

DeepSeek教unity------MessagePack-06

无类型 Typeless 无类型的 API 类似于 BinaryFormatter&#xff0c;因为它会将类型信息嵌入到数据块中&#xff0c;所以在调用 API 时不需要显式指定类型。 MessagePackSerializer.Typeless 是 Serialize/Deserialize<object>(TypelessContractlessStandardResolver.In…...

2.【BUUCTF】bestphp‘s revenge

进入题目页面如下 进行代码审计 <?php // 1. 高亮显示当前PHP文件的源代码&#xff0c;方便开发者查看代码内容&#xff0c;在生产环境中不应使用此函数&#xff0c;可能会导致代码泄露。 highlight_file(__FILE__);// 2. 定义变量 $b &#xff0c;其值为字符串 implode &…...

《刚刚问世》系列初窥篇-Java+Playwright自动化测试-23- 操作鼠标拖拽 - 番外篇(详细教程)

拉票 亲爱的小伙伴们或者童鞋们&#xff0c;喜欢宏哥文章的&#xff0c;请动动你们发财小手&#xff0c;给我投投票票 。 祝2025小伙伴们工作顺利&#xff0c;家庭和睦&#xff0c;心想事成&#xff0c;财源滚滚&#xff01; 我的票还有7票&#xff0c;互票的朋友私信给我。 投…...

Netty源码解析之异步处理(二):盛赞Promise中的集合设计

前言 在阅读Netty源码的过程中&#xff0c;我越来越相信一句话&#xff1a;“Netty的源码非常好&#xff0c;质量极高&#xff0c;是Java中质量最高的开源项目之一”。如果认真研究&#xff0c;会有一种遍地黄金的感觉。 本篇文件我将记录一下鄙人在Promise的实现类DefaultPr…...

NetworkX布局算法:nx.spring_layout

诸神缄默不语-个人CSDN博文目录 官方文档&#xff1a;https://networkx.org/documentation/stable/reference/generated/networkx.drawing.layout.spring_layout.html 和nx.fruchterman_reingold_layout()等价。 这个函数主要是为了在可视化NetworkX图时设置节点分布布局的&…...

Navicat导入海量Excel数据到数据库(简易介绍)

目录 前言正文 前言 此处主要作为科普帖进行记录 原先Java处理海量数据的导入时&#xff0c;由于接口超时&#xff0c;数据处理不过来&#xff0c;后续转为Navicat Navicat 是一款功能强大的数据库管理工具&#xff0c;支持多种数据库系统&#xff08;如 MySQL、PostgreSQL、…...

LeetCodehot100 力扣热题100 二叉树展开为链表

代码思路 目标&#xff1a; 将二叉树展平&#xff08;flatten&#xff09;为一个单链表。展平后的链表应该按照前序遍历的顺序排列节点&#xff0c;即&#xff1a; • 节点的左子树指针设置为 nullptr。 • 节点的右子树指针指向下一个节点。 代码注释及思路 class Solution…...

2.14学习总结

#include <stdio.h> #include <stdlib.h> #include <math.h>#define MAX_N 32767// 二分查找最接近目标值的元素 int binarySearch(int* arr, int left, int right, int target) {while (left < right) {int mid left (right - left) / 2;if (arr[mid] …...

在WPS中通过JavaScript宏(JSA)调用本地DeepSeek API优化文档教程

既然我们已经在本地部署了DeepSeek,肯定希望能够利用本地的模型对自己软件开发、办公文档进行优化使用,接下来就先在WPS中通过JavaScript宏(JSA)调用本地DeepSeek API优化文档的教程奉上。 前提: (1)已经部署好了DeepSeek,可以看我的文章:个人windows电脑上安装DeepSe…...

zola + github page,用 workflows 部署

之前的Zola都是本地build之后&#xff0c;再push到github上&#xff0c;这种方式很明显的弊端就是只能在本地编辑&#xff0c;而不能通过github编辑&#xff0c;再pull到本地&#xff0c;缺乏了灵活性。因此将zola用workflows来部署。 repo地址&#xff1a;https://github.com/…...

【科技革命】颠覆性力量与社会伦理的再平衡

目录 2025年科技革命&#xff1a;颠覆性力量与社会伦理的再平衡目录技术突破全景图认知智能的范式转移量子霸权实现路径生物编程技术革命能源结构重构工程 产业生态链重构医疗健康新范式教育系统智能进化金融基础设施变革制造范式革命 科技伦理与文明演进 2025年科技革命&#…...

UIView 与 CALayer 的联系和区别

今天说一下UIView 与 CALayer 一、UIView 和 CALayer 的关系 在 iOS 开发中&#xff0c;UIView 是用户界面的基础&#xff0c;它负责处理用户交互和绘制内容&#xff0c;而 CALayer 是 UIView 内部用于显示内容的核心图层&#xff08;Layer&#xff09;。每个 UIView 内部都有…...

Jenkins 新建配置 Freestyle project 任务 六

Jenkins 新建配置 Freestyle project 任务 六 一、新建任务 在 Jenkins 界面 点击 New Item 点击 Apply 点击 Save 回到任务主界面 二、General 点击左侧 Configure Description&#xff1a;任务描述 勾选 Discard old builds Discard old builds&#xff1a;控制何时…...

深入解析A2DP v1.4协议:蓝牙高质量音频传输的技术与实现

1. A2DP概述 A2DP&#xff08;Advanced Audio Distribution Profile&#xff09;是一种高质量音频流媒体协议&#xff0c;旨在实现高质量音频内容的分发&#xff0c;通常用于通过蓝牙设备传输音频数据&#xff0c;例如将音乐从便携式播放器传输到耳机或扬声器。与传统的蓝牙语…...

mybatis-plus逆向code generator pgsql实践

mybatis-plus逆向code generator pgsql实践 环境准备重要工具的版本供参考pom依赖待逆向的SQL 配置文件CodeGenerator配置类配置类说明 环境准备 重要工具的版本 jdk1.8.0_131springboot 2.7.6mybatis-plus 3.5.7pgsql 14.15 供参考pom依赖 <?xml version"1.0&quo…...

Android Studio:RxBus结合ICompositeSubscription使用

我现在想用 RxBus 来发布和订阅事件&#xff0c;同时使用 ICompositeSubscription 来管理订阅。跟前一个博客的区别在于&#xff0c;事件流的产生方式不同&#xff0c;更加得全面。 目标 使用 RxBus 发布事件。使用 ICompositeSubscription 来管理订阅。在 Activity 中创建订…...

微软AutoGen高级功能——Magentic-One

介绍 大家好&#xff0c;博主又来给大家分享知识了&#xff0c;这次给大家分享的内容是微软AutoGen框架的高级功能Magentic-One。那么它是用来做什么的或它又是什么功能呢&#xff0c;我们直接进入正题。 Magentic-One Magnetic-One是一个通用型多智能体系统&#xff0c;用于…...

Leetcode 3577. Count the Number of Computer Unlocking Permutations

Leetcode 3577. Count the Number of Computer Unlocking Permutations 1. 解题思路2. 代码实现 题目链接&#xff1a;3577. Count the Number of Computer Unlocking Permutations 1. 解题思路 这一题其实就是一个脑筋急转弯&#xff0c;要想要能够将所有的电脑解锁&#x…...

论文解读:交大港大上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(一)

宇树机器人多姿态起立控制强化学习框架论文解析 论文解读&#xff1a;交大&港大&上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架&#xff08;一&#xff09; 论文解读&#xff1a;交大&港大&上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化…...

【git】把本地更改提交远程新分支feature_g

创建并切换新分支 git checkout -b feature_g 添加并提交更改 git add . git commit -m “实现图片上传功能” 推送到远程 git push -u origin feature_g...

GruntJS-前端自动化任务运行器从入门到实战

Grunt 完全指南&#xff1a;从入门到实战 一、Grunt 是什么&#xff1f; Grunt是一个基于 Node.js 的前端自动化任务运行器&#xff0c;主要用于自动化执行项目开发中重复性高的任务&#xff0c;例如文件压缩、代码编译、语法检查、单元测试、文件合并等。通过配置简洁的任务…...

20个超级好用的 CSS 动画库

分享 20 个最佳 CSS 动画库。 它们中的大多数将生成纯 CSS 代码&#xff0c;而不需要任何外部库。 1.Animate.css 一个开箱即用型的跨浏览器动画库&#xff0c;可供你在项目中使用。 2.Magic Animations CSS3 一组简单的动画&#xff0c;可以包含在你的网页或应用项目中。 3.An…...

【JVM面试篇】高频八股汇总——类加载和类加载器

目录 1. 讲一下类加载过程&#xff1f; 2. Java创建对象的过程&#xff1f; 3. 对象的生命周期&#xff1f; 4. 类加载器有哪些&#xff1f; 5. 双亲委派模型的作用&#xff08;好处&#xff09;&#xff1f; 6. 讲一下类的加载和双亲委派原则&#xff1f; 7. 双亲委派模…...

Qemu arm操作系统开发环境

使用qemu虚拟arm硬件比较合适。 步骤如下&#xff1a; 安装qemu apt install qemu-system安装aarch64-none-elf-gcc 需要手动下载&#xff0c;下载地址&#xff1a;https://developer.arm.com/-/media/Files/downloads/gnu/13.2.rel1/binrel/arm-gnu-toolchain-13.2.rel1-x…...

消息队列系统设计与实践全解析

文章目录 &#x1f680; 消息队列系统设计与实践全解析&#x1f50d; 一、消息队列选型1.1 业务场景匹配矩阵1.2 吞吐量/延迟/可靠性权衡&#x1f4a1; 权衡决策框架 1.3 运维复杂度评估&#x1f527; 运维成本降低策略 &#x1f3d7;️ 二、典型架构设计2.1 分布式事务最终一致…...

算法打卡第18天

从中序与后序遍历序列构造二叉树 (力扣106题) 给定两个整数数组 inorder 和 postorder &#xff0c;其中 inorder 是二叉树的中序遍历&#xff0c; postorder 是同一棵树的后序遍历&#xff0c;请你构造并返回这颗 二叉树 。 示例 1: 输入&#xff1a;inorder [9,3,15,20,7…...

在鸿蒙HarmonyOS 5中使用DevEco Studio实现指南针功能

指南针功能是许多位置服务应用的基础功能之一。下面我将详细介绍如何在HarmonyOS 5中使用DevEco Studio实现指南针功能。 1. 开发环境准备 确保已安装DevEco Studio 3.1或更高版本确保项目使用的是HarmonyOS 5.0 SDK在项目的module.json5中配置必要的权限 2. 权限配置 在mo…...