深度剖析:为什么 Spring 和 IDEA 都不推荐使用 @Autowired 注解
目录
-
依赖注入简介
-
@Autowired 注解的优缺点
-
Spring 和 IDEA 不推荐使用 @Autowired 的原因
-
构造器注入的优势
-
@Autowired 注解的局限性
-
可读性和可测试性的问题
-
-
推荐的替代方案
-
构造器注入
-
Setter 注入
-
Java Config @Bean 注解
-
-
项目示例:@Autowired vs 构造器注入
-
示例代码
-
可读性和可测试性的对比
-
-
总结
1. 依赖注入简介
依赖注入是一种设计模式,用于实现对象之间的解耦。在传统的编程方式中,一个类通常会直接创建它所依赖的对象,这导致了高度的耦合性和难以进行单元测试。而依赖注入则是通过外部化组件的创建和管理来实现对象间的松耦合。
Spring 框架使用了依赖注入这一设计模式,使得对象的创建和管理更加灵活。例如,下面是一个简单的依赖关系示例:
public class Service {private Repository repository;// 传统的依赖方式public Service() {this.repository = new Repository();}}
在上述代码中,Service 类直接创建了一个 Repository 对象,导致两者之间存在紧密的耦合。而使用依赖注入后,可以改写为:
public class Service {private Repository repository;// 依赖注入public Service(Repository repository) {this.repository = repository;}}
这样,Service 类的依赖通过构造器注入的方式被外部传入,从而实现了解耦。
2. @Autowired 注解的优缺点
在 Spring 框架中,@Autowired 注解用于自动注释框架中所需的依赖。许多开发者在使用 Spring 时,会利用 @Autowired 注解,将其直接应用于类的字段、构造器或 Setter 方法中,以实现自动注入。
@Componentpublic class Service {@Autowiredprivate Repository repository;}
优点
-
易于使用:通过简单地添加 @Autowired 注解,即可实现依赖注入,减少了手工编写代码的复杂性。
-
减少样板代码:@Autowired 注解减少了代码中显示注入所需要的样板代码。
-
自动扫描和装配:Spring 会自动扫描应用程序上下文中的所有 Bean,并进行自动装配,提供了快速开发的便利性。
缺点
-
难以测试:字段注入不便于进行单元测试,特别是在没有 DI 容器(如 Spring Context)的情况下。
-
隐式依赖:@Autowired 注解的使用有时会造成依赖关系的不明显,使代码的读者难以理解对象的依赖结构。
-
不推荐的实践:Spring 官方以及主流开发工具(例如 IntelliJ IDEA)已经不推荐直接使用字段注入。
3. Spring 和 IDEA 不推荐使用 @Autowired 的原因
构造器注入的优势
-
强制依赖变量初始化:通过构造函数注入,类在实例化时必须注入所有依赖,确保了依赖变量在类实例化时就能够被正确初始化。
-
不变性:构造函数注入提倡依赖变量的不变性(final),这样可以确保引用一旦被注入,便不会被更改,从而提高了代码的安全性和可维护性。
-
简化测试:通过构造函数注入,可以方便地进行单元测试而无需启动整个 Spring 容器,只需传递模拟对象(Mock objects)即可。
@Autowired 注解的局限性
-
反射开销:使用 @Autowired 注解时,Spring 容器在运行时需要使用反射机制来注入依赖,这带来了额外的性能开销。
-
隐式依赖关系:当使用字段注入时,依赖关系变得隐式,这会导致代码的可读性下降,需要更多文档和注释解释类的依赖关系。
-
代码可维护性差:当类的依赖越来越多时,使用 @Autowired 注解会使代码变得复杂,增加了维护的难度。
可读性和可测试性的问题
-
代码可读性差:@Autowired 注解使外部依赖的绑定显得不够直观,开发者在阅读代码时需要额外的心智负担来追踪依赖关系。
-
增加测试复杂性:使用字段注入会使单元测试变得困难,因为需要在测试中启动 Spring 容器或使用反射来初始化依赖对象。
-
脆弱性:如果依赖对象未正确注入,@Autowired 注解的字段会处于不确定状态,这可能会在运行时导致 NullPointerException。
4. 推荐的替代方案
虽然 @Autowired 注解提供了快速实现依赖注入的方式,但从长期的维护性和可测试性考虑,有更为推荐的替代方案:
构造器注入
构造器注入是一种显式的依赖注入方式,可以确保依赖对象在类实例化时被正确注入。这是一种更安全、可测试性更高的注入方式。
@Componentpublic class Service {private final Repository repository;@Autowiredpublic Service(Repository repository) {this.repository = repository;}}
Setter 注入
Setter 注入是一种通过 Setter 方法设置依赖的方式。虽然使用频率相对较低,但在某些需要可选依赖的情况下,Setter 注入是一种灵活的选择。
@Componentpublic class Service {private Repository repository;@Autowiredpublic void setRepository(Repository repository) {this.repository = repository;}}
Java Config @Bean 注解
使用 Java 配置类和 @Bean 注解,可以显式地定义和注入 Bean,从而实现更灵活的依赖注入。
@Configurationpublic class AppConfig {@Beanpublic Repository repository() {return new Repository();}@Beanpublic Service service() {return new Service(repository());}}
5. 项目示例:@Autowired vs 构造器注入
通过一个简单的项目示例,我们可以更直观地理解 @Autowired 和构造器注入之间的区别。
示例代码
使用 @Autowired 注解
@Componentpublic class Service {@Autowiredprivate Repository repository;public void performService() {repository.doSomething();}}@Componentpublic class Repository {public void doSomething() {// 执行数据库操作}}
使用构造器注入
@Componentpublic class Service {private final Repository repository;@Autowiredpublic Service(Repository repository) {this.repository = repository;}public void performService() {repository.doSomething();}}@Componentpublic class Repository {public void doSomething() {// 执行数据库操作}}
可读性和可测试性的对比
可读性
使用构造器注入时,依赖关系显而易见,读者一眼就可以看到该类需要的所有依赖。这使得代码的理解和管理变得更加容易,而不需要额外的注释来解释注入的依赖。
可测试性
使用构造器注入时,可以轻松地进行单元测试,无需启动整个 Spring 容器,只需传递模拟对象即可:
public class ServiceTest {@Testpublic void testPerformService() {Repository mockRepository = mock(Repository.class);Service service = new Service(mockRepository);// 测试业务逻辑service.performService();// 验证方法调用verify(mockRepository).doSomething();}}
而使用 @Autowired 注解时,进行单元测试则变得更为复杂,需要额外的代码启动 Spring 容器或使用反射机制:
@RunWith(SpringRunner.class)@SpringBootTestpublic class ServiceTest {@Autowiredprivate Service service;@MockBeanprivate Repository repository;@Testpublic void testPerformService() {// 测试业务逻辑service.performService();// 验证方法调用verify(repository).doSomething();}}
6. 总结
通过本文的详细分析,我们可以看出为什么 Spring 和 IntelliJ IDEA 都不推荐使用 @Autowired 注解。主要原因包括:
-
构造器注入的优势明显,不仅可以强制依赖变量初始化,还能提高代码的安全性和可维护性。
-
@Autowired 注解的使用会导致代码的隐式依赖关系,降低代码的可读性和可维护性。
-
使用构造器注入或者其它显式的依赖注入方式,可以使代码更易于测试,避免了启动整个 Spring 容器的麻烦。
为了提高代码质量,增强代码的可读性和可测试性,开发者应尽量避免使用 @Autowired 注解,而优先选择构造器注入、Setter 注入或者 Java Config @Bean 注解等显式的依赖注入方式。通过这些替代方案,不仅可以提升代码的整体质量,还能在不同的开发阶段(如维护和测试)中,减少不必要的复杂性和潜在问题。希望本文的分析和建议能为广大开发者提供有价值的参考。
相关文章:
深度剖析:为什么 Spring 和 IDEA 都不推荐使用 @Autowired 注解
目录 依赖注入简介 Autowired 注解的优缺点 Spring 和 IDEA 不推荐使用 Autowired 的原因 构造器注入的优势 Autowired 注解的局限性 可读性和可测试性的问题 推荐的替代方案 构造器注入 Setter 注入 Java Config Bean 注解 项目示例:Autowired vs 构造器…...
【接口自动化_05课_Pytest接口自动化简单封装与Logging应用】
一、关键字驱动--设计框架的常用的思路 封装的作用:在编程中,封装一个方法(函数)主要有以下几个作用:1. **代码重用**:通过封装重复使用的代码到一个方法中,你可以在多个地方调用这个方法而不是…...
信息学奥赛初赛天天练-14-阅读程序-字符数组、唯一分解定理应用
更多资源请关注纽扣编程微信公众号 1 2019 CSP-J 阅读程序1 (程序输入不超过数组或字符串定义的范围;判断题正确填√,错误填;除特殊说明外,判断题1.5分,选择题3分,共计40分) 1 输入的字符串只能由小写字母或大写字母组…...
K210 数字识别 笔记
一、烧写固件 连接k210开发板,点开烧录固件工具,选中固件,并下载 二、模型训练 网站:MaixHub 1、上传文件 2、开始标记数据 添加9个标签,命名为1~9,按键盘w开始标记,键盘D可以下一张图片&…...
人脸检测--FaceNet(四)
FaceNet 是一个由 Google 研究团队开发的人脸识别系统,它基于深度学习技术,可以实现高精度的人脸识别、验证和聚类任务。FaceNet 通过学习直接从图像像素到人脸嵌入的映射,使得它在各种人脸识别任务中表现出色。下面是对 FaceNet 的详细介绍&…...
Android性能优化方案
1.启动优化: application中不要做大量耗时操作,如果必须的话,建议异步做耗时操作2.布局优化:使用合理的控件选择,少嵌套。(合理使用include,merge,viewStub等使用)3.apk优化(资源文件优化&#…...
视频监控平台AS-V1000 的场景管理,一键查看多画面视频的场景配置、调用、管理(一键浏览多路视频)
目录 一、场景管理的定义 二、场景管理的功能和特点 1、功能 (1)场景配置 (2)实时监控 (3)权限管理 2、特点 三、AS-V1000的场景配置和调用 1、场景配置 (1)实时视频预览 …...
微服务架构五大设计模式详解,助你领跑行业
微服务架构设计模式详解(5种主流模式) 微服务架构 微服务,一种革命性的架构模式,主张将大型应用分解为若干小服务,通过轻量级通信机制互联。每个服务专注特定业务,具备独立部署能力,轻松融入生产环境,为系…...
【problem】解决EasyExcel导出日期数据显示为#####问题
前言 在使用EasyExcel进行数据导出时,你可能遇到日期或其他数据在Excel中显示为“#######”的情况,这通常是因为列宽不足以展示单元格内的全部内容。本文将指导你如何通过简单的步骤解决这一问题,并确保导出的Excel文件自动调整列宽或直接指…...
Pytest用例自定义 - 重复、并行、串行
简介:面对快速迭代和持续交付的需求,提高测试效率变得至关重要。并行测试因其显著的时间节省优势而备受青睐。然而,并非所有测试都适合并行执行。在某些情况下,串行执行是必要的,以确保测试的正确性和稳定性。本文将探…...
前端项目上线
目录 1项目打包 2本地服务器部署 2.1具体操作步骤 2.2解决刷新 404 问题 2.3请求无法发送问题 3nginx 服务器部署 3.2nginx 配置代理练习 安装nginx nginx部署启动项目 3.3nginx 部署前端项目 4云服务器部署 本地资源上传 配置服务器与nginx 1项目打包 ●我…...
redis基本数据结构与应用
文章目录 概要String结构Hash结构List结构Set结构Zset结构bitmap位图类型geo地理位置类型其他常用命令 概要 redis常用的5种不同数据结构类型之间的映射如下: 结构类型结构存储的值结构的读写能力STRING可以是字符串、整数或者浮点数key-value形式;对整…...
Python pands使用引擎实现excel条件格式
截至我的知识更新日期(2023年),Pandas 库本身并不直接支持Excel条件格式。Pandas 是一个强大的Python数据分析库,它主要用于数据分析和操作,而不是用于创建或编辑Excel文件的格式。 然而,你可以使用 openp…...
基于 vuestic-ui 实战教程 - 登录篇
1. 简介 登录做为一个系统的门面,也是阻挡外界的一道防线,那在vuestic-ui中如何做登录功能呢。在这里就之间沿用初始版本的Login页面,作为一个演示模板,后续需要改进的读者可以在此篇文章的基础上修改。 2. 登录接口相关api 与 t…...
SAPUI5基础知识2 - 手动创建一个SAPUI5的项目
1. 前言 在本篇文章中,我们将手动一步一步建立出第一个SAPUI5的 ‘Hello World!’ 项目。 2. 步骤详解 2.1 在BAS中建立Dev Space 进入SAP Business Application Studio的Dev Space Manger,选择创建Dev Space。 勾选HTML5 Application Template插件…...
设计模式--访问者模式
访问者模式是一种行为设计模式,它用于将算法与对象结构分离,使得算法可以独立于使用它的数据结构而变化。这种模式在许多应用场景中非常有用,例如在实现图形算法、数据结构遍历、文件格式转换以及代码分析时。 应用场景 图形算法࿱…...
onnx模型转换到rknn脚本
from rknn.api import RKNN ONNX_MODEL ./onnx_models/yolov5s_rm_transpose.onnx # platform"rk1808" platform "rv1109" RKNN_MODEL yolov5s_relu_{}_out_opt.rknn.format(platform) if __name__ __main__: add_perm False # 如果设置成True,则将模…...
防御恶意爬虫攻击
数据抓取爬虫 数据抓取爬虫是攻击者使用自动化脚本或工具在移动应用程序中抓取敏感数据的一种方式。这些爬虫可以定向抓取用户信息、产品列表、评论和评级等数据。攻击者可能会将这些数据用于非法目的,例如进行身份盗窃、诈骗活动或者卖给其他恶意方。 对于移动应用…...
【自动驾驶技术栈学习】2-软件《大话自动驾驶》| 综述要点总结 by.Akaxi
----------------------------------------------------------------------------------------------------------------- 致谢:感谢十一号线人老师的《大话自动驾驶》书籍,收获颇丰 链接:大话自动驾驶 (豆瓣) (douban.com) -------------…...
SRS视频服务器应用研究
1.SRS尝试从源码编译启动 1.1.安装ubuntu 下载镜像文件 使用VMWare安装,过程中出现蓝屏,后将VM的软件版本从15.5升级到17,就正常了。 1.2.更新ubuntu依赖...
RISC-V SoC中TileLink互连验证IP的设计与实战应用
1. 项目概述:为什么RISC-V SoC需要一个专门的TileLink验证IP?如果你正在设计或验证一个基于RISC-V的片上系统(SoC),尤其是当它集成了多个处理器核心、加速器、DMA控制器和各种内存控制器时,那么“互连”这个…...
STM32F407的PWM呼吸灯太简单?试试用DMA+定时器实现‘无CPU干预’的渐变效果
STM32F407的PWM呼吸灯进阶:DMA定时器实现零CPU占用的智能光效 在嵌入式开发中,PWM呼吸灯常被视为入门级练习,但将其提升到工业级应用时,传统CPU轮询方式会暴露明显缺陷。当系统需要同时处理网络通信、传感器采集等任务时ÿ…...
废水污染源在线监测管理平台方案
某企业从事染整加工生产,属于环境监管重点单位,安装有废水自动处理系统,监控因子包括PH值、化学需氧量、氨氮、总氮等。但在某次巡查工作时发现,化学需氧量远远超过排放标准,但涉事企业却未上报排放超标的情况。因此要…...
X.509证书格式(SPDM协议)
字段名称含义用途示例待签名内容(tbsCertificate)Version (版本)含义: 证书版本号。取值: v1(0), v2(1), v3(2)。互联网 PKI 必须使用 v3 (值为 2)。告诉解析程序该按照哪个标准来读取后续的字段(目前绝大多数为 v3)。Version: 3 (0x2)Serial Number (序…...
干货 | 细胞功能学实验合集
细胞增殖实验细胞增殖、凋亡及细胞周期调控,是肿瘤学研究中的核心表型指标,同时也是分子生物学与药理学领域的重点研究方向。在实验研究中,研究者通常通过在细胞内实现特定基因的过表达或干扰,来探究该基因对细胞增殖的调控作用&a…...
EPM900编程器HEX文件烧录指南与技巧
1. EPM900编程器与HEX文件烧录概述 EPM900是Keil公司推出的一款LPC系列微控制器仿真编程器,主要用于NXP LPC系列ARM芯片的调试与程序烧录。在实际工程开发中,我们经常需要将编译生成的HEX文件直接烧录到目标芯片中,而EPM900恰好支持这一功能。…...
如何让老旧游戏手柄重获新生:XOutput输入转换器完整指南
如何让老旧游戏手柄重获新生:XOutput输入转换器完整指南 【免费下载链接】XOutput DirectInput to XInput wrapper 项目地址: https://gitcode.com/gh_mirrors/xo/XOutput 你是否拥有一些老旧但质量优秀的游戏手柄、摇杆或方向盘,却发现在现代游戏…...
Perplexity vs ChatGPT vs Claude:用户评论情感分析对比报告(NLP模型实测,含21项维度打分)
更多请点击: https://intelliparadigm.com 第一章:Perplexity用户评论汇总 主流平台用户反馈概览 Perplexity 作为以引用驱动、实时联网为特色的AI问答工具,近期在Reddit、Product Hunt及Twitter等平台收获大量真实用户评论。高频关键词包括…...
树莓派Web IDE:零配置云端编程环境与Python硬件模拟实践
1. 项目概述:一个“开箱即用”的编程环境革命最近,树莓派基金会悄无声息地扔下了一颗“重磅炸弹”——他们正式推出了一个网页端的代码编辑器。这个消息在创客圈和教育圈里,可能比发布一款新硬件还要让人兴奋。为什么?因为它直接戳…...
Windows 10/11下,手把手教你用Python2和Git搞定GitHack(附常见错误解决)
Windows 10/11下Python2与Git环境搭建及GitHack实战指南 在网络安全和CTF竞赛领域,.git文件夹泄露是一个常见但危险的漏洞。GitHack作为一款专门针对此类漏洞的利用工具,能够帮助安全研究人员快速还原网站源代码。本文将详细介绍在Windows 10/11系统上配…...
