@Autowired 关键字做了什么?它和“依赖注入”是什么关系?

深度剖析:为什么 Spring 和 IDEA 都不推荐使用 @Autowired 注解 在 Spring 框架开发中,@Autowired 注解曾经是依赖注入(DI)的“标配”,开发者习惯用它快速实现 Bean 的自动装配。然而,随着 Spring 版本的迭代和开发实践的演进,官方文档和主流 IDE(如 IntelliJ IDEA)逐渐不推荐直接使用 @Autowired 注解,甚至会在代码中给出警告提示。这背后隐藏着哪些设计哲学和工程问题?本文将从技术原理和最佳实践的角度,解析这一变化的原因。 阅读详情

@Autowired 和“依赖注入”的关系,就像“插头”和“用电”的关系。


“依赖注入”是什么?

依赖注入 (Dependency Injection, DI) 是一种设计模式和原则。

它的核心思想是:一个组件(对象)不应该自己去创建它所依赖的另一个组件,而应该由外部的“某人”(IoC 容器)把这个依赖“送”给它。

  • 目标 (What):实现解耦,让组件只关注自己的业务,不关心依赖从哪来。
  • 角色 (Who):
    • 依赖方:需要别人帮助的组件(比如 MyController)。
    • 被依赖方:提供帮助的组件(比如 MyService)。
    • 注入者:负责协调和执行注入动作的“某人”(Spring IoC 容器)。

依赖注入是一种行为,一个过程。


@Autowired 关键字做了什么?

@Autowired 是一个注解,它是一种指令或标记。

它的作用是告诉 Spring IoC 容器:“嘿!我(这个类)需要一个依赖,请在运行时把一个合适的 Bean 注入到这个位置!”

  • 目标 (What):向 Spring 容器发出一个“自动装配”的请求。
  • 角色 (Who):
    • 标记位置:你可以把它放在字段、构造函数或 Setter 方法上,指定注入点。
    • 执行者:Spring IoC 容器里的一个特殊组件(AutowiredAnnotationBeanPostProcessor)会去寻找并处理这个注解。

@Autowired 是触发依赖注入这个行为的开关或扳机。

@Autowired 与“依赖注入”的关系

@Autowired 是实现“依赖注入”的一种具体方式。

让我们用一个生动的比喻来理解:

  • 依赖注入 (DI):就像是“家用电器需要用电”这个概念。
  • Spring IoC 容器:是整个城市的电网系统。
  • 你的 Bean (@Service, @Component等):是电网里的各种电器,比如电视机、冰箱。
  • @Autowired:就是你在墙上安装的那个电源插座。

整个流程是这样的:

  1. 声明需求:你在你的 MyController 类(电视机)的 myService 字段(电源线)上加了 @Autowired 注解。这等于你对电工(Spring 容器)说:“我这台电视机需要电,请在这里给我留一个插座!”
  2. 容器准备:Spring 容器在启动时,会创建并管理好所有的 Bean(电网里已经有了稳定的电力供应,并且知道每个电器的位置)。
  3. 执行注入:当 Spring 容器创建 MyController 这个 Bean 时,它会检查这个类。
    • 它看到了 @Autowired 这个“插座”。
    • 它会根据 myService 字段的类型(MyService.class)去电网(IoC 容器)里寻找一个匹配的 Bean(寻找可用的电源)。
    • 找到后,它就把 MyService 的实例注入(赋值)给 myService 字段。这个动作就像把电视机的插头插进插座里。

所以,它们的关系是:

  • DI 是一个宏观的模式(我要用电)。
  • @Autowired 是一个微观的实现工具(我需要一个插座来用电)。

@Autowired 的三种注入方式(三种“插座”的位置)

@Autowired 可以放在三个不同的地方,Spring 官方最推荐构造函数注入。

1. 字段注入 (Field Injection) - 【最简洁,但不推荐】
@RestController
public class MyController {
    @Autowired
    private MyService myService; // 直接在字段上加注解

    // ...
}
  • 优点:代码最少,看起来最干净。
  • 缺点:
    • 可测试性差:在单元测试中,你无法在不启动 Spring 的情况下,轻松地为 myService 设置一个 Mock 对象。
    • 隐藏依赖:依赖关系被隐藏在类的内部,不够清晰。
    • 可能导致循环依赖:这种方式更容易写出循环依赖的代码。
2. Setter 方法注入 (Setter Injection) - 【较少使用】
@RestController
public class MyController {
    private MyService myService;

    @Autowired
    public void setMyService(MyService myService) { // 在Setter方法上加注解
        this.myService = myService;
    }
    // ...
}
  • 优点:允许注入可选的依赖(如果 myService 不是必须的)。
  • 缺点:对象在创建后,其依赖关系可能被改变,违反了“不变性”原则。
3. 构造函数注入 (Constructor Injection) - 【官方推荐】
@RestController
public class MyController {
    private final MyService myService; // 可以声明为 final,确保不变性

    // 在构造函数上加注解
    // 在只有一个构造函数的情况下,@Autowired 注解可以省略
    @Autowired 
    public MyController(MyService myService) {
        this.myService = myService;
    }
    // ...
}
  • 优点:
    • 依赖清晰:所有必需的依赖都在构造函数中一目了然。
    • 保证不变性:依赖可以被声明为 final,一旦注入就不会被改变,保证了线程安全。
    • 保证对象可用性:对象一旦被创建,它所必需的依赖就已经准备就绪,不会出现 NullPointerException。
    • 极佳的可测试性:在单元测试中,你可以非常简单地 new MyController(new MockMyService()),完全不需要 Spring 容器的介入。

总结

概念角色描述
依赖注入 (DI)设计模式/原则一种思想:组件的依赖由外部容器来提供,以实现解耦。
@Autowired注解/指令Spring 框架中实现 DI 的一种工具,它告诉容器“请在这里注入一个 Bean”。

@Autowired 是你向 Spring 发出的一个请求,而 Spring 响应这个请求并为你完成依赖的传递,这个过程就是依赖注入。

Linux下libdrm实战:从零搭建一个简单的DRM显示程序(附完整代码) 本文是一份Linux下libdrm的实战指南,详细介绍了如何从零开始搭建一个简单的DRM显示程序。通过对比传统Framebuffer的局限性,阐述了现代DRM架构的核心优势与核心对象(FrameBuffer、Plane、CRTC等)的协作流程。文章提供了完整的代码示例,演示了如何打开设备、创建并填充Dumb Buffer、设置CRTC以依次显示红绿蓝纯色画面,并涵盖了编译、运行及进阶开发要点,为嵌入式Linux图形开发提供了扎实的入门基础。 阅读详情

相关推荐

基于深度学习的干扰识别

本文是记录我上半年仿真和复现干扰识别的过程,展示的主要是一些需要注意的点以及仿真的相关结果。

qq_55218335的博客 1702

想用@Autowired注入static静态成员?官方不推荐你却还偏要这么做

Spring依赖注入static静态成员(属性、方法),这里的坑谁用谁知道

架构师:通透,才能写出好代码! 8563

Unity2020 发布Android包,下载安装配置JDK、SDK、NDK详细教程

配置成功页面 JDK、SDK、NDK

qq_41263535的博客 1万+

@Autowired和static的关系

一 发生的场景   好几次有个同事因为把static用到Spring的@Autowired上,导致注入的对象一直报空指针,他一直找不到错误在哪里,来问我,其实我以前也不知道这个问题,但我根据Spring容器的特点判定,他调用的对象与注入的对象不是一个对象,就告诉他:static的加载顺序是在@Autowired之前;之后查资料才知道其实不是这样。。。 二 原理剖析     静...

dibai1921的博客 1950

BambuStudio学习笔记:OpenCSG - 实时构造实体几何(CSG)渲染的 OpenGL 方案

**OpenCSG** 是一个基于 **OpenGL** 的 **构造实体几何(CSG)** 实时渲染库,通过 **深度剥离算法** 实现布尔运算(并集、交集、差集)的可视化。其核心目标是简化复杂几何体的交互式建模,适用于 CAD 原型设计、3D 打印预览、教育工具等场景。

zzzkk2009的专栏 928

2024年【MCM/ICM】美国大学生数学建模竞赛优秀论文(免费下载)

美国大学生数学建模竞赛(MCM/ICM)由美国数学及其应用联合会主办,是最高的国际性数学建模竞赛,也是世界范围内最具影响力的数学建模竞赛,一般也指数学建模竞赛。赛题内容涉及经济、管理、环境、资源、生态、医学、安全、等众多领域。竞赛要求三人(本科生和研究生均可参加)为一组,在四天时间内,就指定的问题完成从建立模型、求解、验证到论文撰写的全部工作,体现了参赛选手研究问题、解决方案的能力及团队合作精神。为现今各类数学建模竞赛之鼻祖。

weixin_43608857的博客 1839

使用@Autowired依赖注入静态成员(属性)。

前言 本文继续来聊聊static关键字更为常见的一种case:使用@Autowired依赖注入静态成员(属性)。 在Java中,针对static静态成员,我们有一些最基本的常识:静态变量(成员)它是属于类的,而非属于实例对象的属性;同样的静态方法也是属于类的,普通方法(实例方法)才属于对象。而Spring容器管理的都是实例对象,包括它的@Autowired依赖注入的均是容器内的对象实例,所以对于static成员是不能直接使用@Autowired注入的。 这很容易理解:类成员的初始化较早,并不需要依赖

asd43211234的博客 2357

arkts编译报错-arkts-limited-stdlib错误【Bug已完美解决-鸿蒙开发】

在使用 Deveco Studio 4.0 beta2 开发应用时,报错。ERROR: ArkTS:ERROR File: D:/prRevivw/3792/applications_appsamg优快云o”见台难忘Usage of standardlibrary is restricted (arkts-limited-stdlib)这是 ArkTS 新增的语法规则。

一键难忘的博客 3775

终于有人把@Autowired 和 @Resource 的区别说清楚了!

@Autowired 和 @Resource 的区别

LJJ555a的博客 6372

YOLOv8【第十二章:数据增强与数据工程篇·第10节】主动学习(Active Learning):如何挑选最有价值的样本进行标注!

🏆 本文收录于 《YOLOv8实战:从入门到深度优化》 专栏。该专栏系统复现并梳理全网各类 YOLOv8 改进与实战案例(当前已覆盖分类 / 检测 / 分割 / 追踪 / 关键点 / OBB 检测等方向),坚持持续更新 + 深度解析,质量分长期稳定在 97 分以上,可视为当前市面上 覆盖较全、更新较快、实战导向极强 的 YOLO 改进系列内容之一。

**My Coding Family** 508

第一节:Vben Admin介绍和初次运行

本文是【实战Vben Admin + Python】的第一节,本文内容主要是介绍Vben Admin框架和我们后端使用的技术,开发环境和工具的准备本节文章的目的是Vben Admin的简单介绍,通过配置可以让项目前端运行起来,由于项目默认开启了mock,展示的都是静态模拟数据,我们在此基础上,下一节将研究分析下Vben Admin的目录。为我们后端搭建准备。

cuiwin的专栏 7410

spring系列之——使用@Autowired注解,不建议基于字段的依赖注入

介绍 使用@Autowired注解基于字段的依赖注入时,IDEA会出现弱警告,如下: 思考:为什么不推荐使用,这种方式是不是有更好的替代方案。 依赖注入方式 依赖注入有三种方式: 基于字段注入 基于构造器注入 基于set方法注入 1、基于字段注入 @Service public class EmployeeServiceImpl implements EmployeeService { @Autowired private EmployeeMapper emp...

weixin_59744818的博客 1万+

ESP32-CAM 赋能 AI 视觉巡检小车:自主避障与目标追踪实现全解析

本文基于 ESP32-CAM 实现了低成本 AI 视觉巡检小车的核心功能,硬件成本<100 元,兼顾自主避障与目标追踪。算法升级:移植 YOLOv5nano 量化模型(INT8),提升目标检测精度(如识别巡检场景中的 “异常物体”“人员”);无线拓展:通过 MQTT 协议将巡检图像、距离数据上传到阿里云 / 腾讯云,实现远程监控;多传感器融合:增加温湿度(DHT11)、红外测温(MLX90614)模块,扩展巡检维度;路径规划:结合 SLAM 算法,实现自主建图与路径巡检。

weixin_42300449的博客 367

【Spring】@Autowired和@Resource关键字的区别

@Resource的作用相当于@Autowired,只不过@Autowired按照byType自动注入。

Java领域优质创作者,华为云享专家 1461

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

@Autowired依赖注入

依赖注入的三种方式: 基于字段注入 基于构造器注入 基于set方法注入

m0_46192140的博客 1640

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

@Autowired和@Resource的区别

对比项@Autowired@Resource来源Spring 提供Java EE(JSR-250)规范注入方式默认按类型(byType),可配合@Qualifier默认按名称(byName),找不到时按类型支持范围构造方法、setter、字段、方法参数setter、字段(不支持构造方法)是否支持required可选不支持是否需要 Spring是否(可用于其他 Java EE 容器)

2404_87525603的博客 833

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

Spring源码分析の依赖注入(@AutoWired模式)

在Spring中,进行依赖注入最常见的方式是@AutoWired和@Resource。其中默认按类型(byType)查找,如果找到多个匹配的Bean,则按名称(byName)查找。而@Resource是先根据名称查找,如果(根据名称)查找不到,再根据类型进行查找。@AutoWired在源码中的体现,主要在于:在实例化后,依赖注入前预先寻找注入点在实例化后,初始化前,进行注入Spring 在实例化后,初始化前,扫描标记了该注解的属性或者方法,作为注入点缓存。

西岭千秋雪的博客 1293

Spring Boot学习笔记(十六)@Autowired和使用 new()区别

1.使用上的区别 大家在使用@Autowired注解的时候,肯定会有疑惑,这个地方我使用@Autowired注入,和我使用new,这种写法的作用有什么区别呢? 最重要的一点,使用new创建的对象,无法调用Spring容器内的实例。 即 new出来的对象无法调用@Autowired注入的Spring Bean,否则报空指针异常, @Autowired注入Spring Bean,则当前类必须也是Spring Bean才能调用它,不能用new xxx()来获得对象,这种方式获得的对象无法调用@Autowired注

TUTsmile的博客 4669

Spring依赖注入的三种方式:@Autowired、@Resource、@Inject的全面对比与最佳实践

在软件工程领域,依赖注入(Dependency Injection, DI)作为一种设计模式,已经成为现代Java应用开发的核心范式。它的核心思想是将对象间的依赖关系从代码内部转移到外部容器来管理,通过"注入"的方式将依赖对象传递给需要它的组件。这种机制不仅遵循了"控制反转"(IoC)原则,更显著提高了代码的可测试性、可维护性和灵活性。

zuiyuelong的博客 1156

为什么使用构造注入而不是@Autowired

一、前言     使用Spring开发时,我们通常有两种依赖注入的方式,基于注解@Autowired的依赖注入和基于构造函数的依赖注入。用IDEA开发过程中,如果使用@Autowired注入,通常会有如下警告: Inspection info: Spring Team recommends: "Always use constructor based dependency injection in your beans. Always use assertions

weixin_42146366的博客 3177

@Autowired注解和静态方法以及new的关系

一、@autowired 与new   new出来的对象无法调用@Autowired注入的Spring Bean,否则报空指针异常, @Autowired注入Spring Bean,则当前类必须也是Spring Bean才能调用它,不能用new xxx()来获得对象,这种方式获得的对象无法调用@Autowired注入的Bean。 二、@autowired 与静态方法 1.spring框架应...

xuhaogang3的博客 3632

springboot 中@Autowired和 new()对象的区别

1.使用上的区别 在使用@Autowired注解的时候,肯定会有疑惑,这个地方我使用@Autowired注入,和我使用new,这种写法的作用有什么区别呢? 最重要的一点,使用new创建的对象,无法调用Spring容器内的实例。 即 new出来的对象无法调用@Autowired注入的Spring Bean,否则报空指针异常, @Autowired注入Spring Bean,则当前类必须也是Spring Bean才能调用它,不能用new xxx()来获得对象,这种方式获得的对象无法调用@Autowired

jimzhking的博客 5406

Spring @Autowired注入为 null 的原因总结

原因 配置缺失,比如为开启注解扫描驱动、注入组件为注册; 使用 new 关键字创建的对象不受spring容器管理,无法注入; 注入静态变量, 静态变量/类变量不是对象的属性,而是一个类的属性,spring则是基于对象层面上的依赖注入。 静态注入的三种方式 在一些工具类中可能会依赖 service 层的对象,一般情况下工具类都是使用静态方法,对应的成员变量也需要声明为静态的,此时如果直接使用 @...

伏念先生的博客 3万+

@Autowired 和 @Resource 有什么区别?

@Autowired 和 @Resource 都是 Spring/Spring Boot 项目中,用来进行依赖注入的注解。它们都提供了将依赖对象注入到当前对象的功能,但二者却有众多不同,并且这也是常见的面试题之一,所以我们今天就来盘它。 @Autowired 和 @Resource 的区别主要体现在以下 5 点: 来源不同; 依赖查找的顺序不同; 支持的参数不同; 依赖注入的支持不同; 编译器 IDEA 的提示不同。 1.来源不同 @Autowired 和 @Resource 来自不同的“父类”

分享Java技术知识,共同成长进步! 958

【Spring】 @Autowired 和 @Resource关键字的区别

@Autowired 和 @Resource的来源、注入方式、依赖注入的支持不同

阿羊ing努力提供更好的Java日记〜 454

@Autowired和@Resource到底有什么区别

@Autowired 和 @Resource 都是 Spring/Spring Boot 项目中,用来进行依赖注入的注解。它们都提供了将依赖对象注入到当前对象的功能,但二者却有众多不同,并且这也是常见的面试题之一,所以我们今天就来盘它。 @Autowired 和 @Resource 的区别主要体现在以下 5 点: 1.来源不同; 2.依赖查找的顺序不同; 3.支持的参数不同; 4.依赖注入的用法不同; 5.编译器 IDEA 的提示不同。

_江屿_ 263
上一篇: 我们通常写的 Bean 都被放在哪里管理?
下一篇: @Component, @Service, @Repository, @Controller 有什么本质区别吗?为什么需要这么多不同的注解?
冰糖心书房
博客等级 码龄15年 6014粉丝 690原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

冰糖心书房

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值