讲师中心 微信公众号
AI工具推荐 视频效率加速

详解Java中的依赖注入 (Dependency Injection)_解耦对象创建与使用的思想

大敏吖_8436

大敏吖_8436

发布时间:2026-02-21 16:58:03

|

957人浏览过

|

来源于php中文网

原创

依赖注入本质是将对象创建与使用解耦,A只管用B而不操心其构造;Spring中@Autowired失效主因有三:字段未被扫描、目标类未注册、手动new绕过容器;构造器注入优于字段注入,因其保障对象完整性和线程安全。

详解java中的依赖注入 (dependency injection)_解耦对象创建与使用的思想

为什么 new 一个对象会让人头疼

因为硬编码的 new 把对象创建和使用死绑在一起。一旦类 A 依赖类 B,而 B 的构造方式变了(比如要加参数、换实现、加日志代理),所有调用 new B() 的地方都得改——这不是写代码,是批量修 bug。

依赖注入的本质不是“用框架”,而是把“谁来造 B”这个问题,从 A 内部移出去。A 只管用,不操心 B 怎么来。

  • 常见错误现象:NullPointerException 频发,但堆栈里找不到明显空指针位置——其实是注入没生效,字段仍是 null
  • 典型场景:单元测试时想替换成 Mock 对象,却发现 A 里直接 new B(),根本没法替换
  • 关键区别:手动 new 是「主动拉取」,DI 是「被动接收」;前者控制权在使用者,后者在容器或调用方

Spring 中 @Autowired 注入失败的三个高频原因

@Autowired 看似一行搞定,实际失效时连日志都不报错,静默失败最伤人。

  • 字段没加 public/protected 修饰,且类没被 Spring 扫描到(比如放在 src/test/java 下却没配 @TestConfiguration)
  • 目标类没加 @Component、@Service 等注解,或者虽然加了但包路径不在 @ComponentScan 范围内
  • 用了 new A() 手动实例化,绕过了 Spring 容器——此时哪怕 A 类里有 @Autowired,字段也一定是 null

验证是否生效?加个构造函数或 @PostConstruct 方法,打印该字段是否为 null,比看文档快得多。

立即学习“Java免费学习笔记(深入)”;

Java调试
Java调试

通过 JDWP 实现 Java 远程调试:连接远程 JVM、设置断点、单步执行代码、查看变量值、获取调用栈。适用于需要调试远程 Java 应用、排查运行时状态、追踪代码执行流程的场景。 术语注解 JDWP:Java Debug Wire Protocol,Java 调试有线协议(Java 远程调试底层通信协议) remote JVM:远程 Java 虚拟机 step through code:代码单步调试(步入 / 步过 / 步出调试) inspect variables:变量查看 / 变量检视 stac

下载

构造器注入 vs 字段注入:选哪个不是风格问题,是生命周期问题

字段注入(@Autowired private B b;)写起来爽,但会让对象处于「半初始化」状态:实例已存在,依赖却还没塞进来。这对不可变性、线程安全、测试隔离都是隐患。

  • 构造器注入强制你在创建时就提供所有必需依赖,对象一出生就是完整的——final 字段能用,NullPointerException 少一半
  • 字段注入在 Lombok 的 @RequiredArgsConstructor 配合下可兼顾简洁,但注意:Lombok 生成的构造器不会自动加 @Autowired,得手动补上
  • 循环依赖时,Spring 默认只对 setter/字段注入做代理处理,构造器注入会直接抛 BeanCurrentlyInCreationException

如果类只有 1–2 个依赖,构造器注入几乎零成本;超过 5 个?先想想这个类是不是该拆了。

不用 Spring 也能做依赖注入:手写一个最小可用版

DI 不是 Spring 的专利。理解它,靠一个 Map<class>, Object></class> + 反射就能跑通核心逻辑。

// 简单容器伪代码
private Map<Class<?>, Object> beans = new HashMap<>();
public <T> void register(Class<T> type, T instance) {
    beans.put(type, instance);
}
public <T> T get(Class<T> type) {
    return (T) beans.get(type);
}

真正难的是自动装配:扫描类、解析构造器参数、递归获取依赖……这些 Spring 做了十几年才稳下来。自己造轮子前,先问一句:你真需要绕过 Spring 的 AOP、事务、异步等配套能力吗?

多数时候,卡住你的不是 DI 思想,而是没分清「谁负责创建」「谁负责传递」「谁负责销毁」这三件事。漏掉任一环,对象就会在某个深夜突然变成 null。

热门AI工具

更多
豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

Seko
Seko Hot

一款AI视频创作工具,主要用于商汤科技推出的创编一体的AI短视频创作Agent,适合需要提升相关任务效率的用户。

Flowith
Flowith Hot

Flowith是一款基于画布和智能体工作流的 AI 协作工作空间。

蛙蛙写作

一款AI论文写作工具,主要用于超级AI智能写作助手,适合需要提升相关任务效率的用户。

码上飞
码上飞 Hot

一款基于自然语言的AI应用开发平台,可根据用户描述自动生成应用程序,帮助个人和团队快速完成应用原型与开发。

Loomy
Loomy Hot

一款AI工具,主要用于科大讯飞发布的桌面级 AI 助理,比 OpenClaw 更易用、更安全!,适合需要提升相关任务效率的用户。

PixTV
PixTV Hot

PixTV是一款面向AIGC内容创作的AI视频生成工具。

WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

相关专题

更多
spring框架介绍
spring框架介绍

本专题整合了spring框架相关内容,想了解更多详细内容,请阅读专题下面的文章。

2831

2025.08.06

Java Spring Security 与认证授权
Java Spring Security 与认证授权

本专题系统讲解 Java Spring Security 框架在认证与授权中的应用,涵盖用户身份验证、权限控制、JWT与OAuth2实现、跨站请求伪造(CSRF)防护、会话管理与安全漏洞防范。通过实际项目案例,帮助学习者掌握如何 使用 Spring Security 实现高安全性认证与授权机制,提升 Web 应用的安全性与用户数据保护。

517

2026.01.26

c语言中null和NULL的区别
c语言中null和NULL的区别

c语言中null和NULL的区别是:null是C语言中的一个宏定义,通常用来表示一个空指针,可以用于初始化指针变量,或者在条件语句中判断指针是否为空;NULL是C语言中的一个预定义常量,通常用来表示一个空值,用于表示一个空的指针、空的指针数组或者空的结构体指针。

549

2023.09.22

java中null的用法
java中null的用法

在Java中,null表示一个引用类型的变量不指向任何对象。可以将null赋值给任何引用类型的变量,包括类、接口、数组、字符串等。想了解更多null的相关内容,可以阅读本专题下面的文章。

1698

2024.03.01

C++ 智能指针与现代内存管理
C++ 智能指针与现代内存管理

深入讲解 C++ 现代内存管理的核心工具——智能指针,涵盖 unique_ptr 独占所有权语义、shared_ptr 引用计数机制与循环引用问题、weak_ptr 弱引用的应用场景、make_unique/make_shared 工厂函数的性能优势、自定义删除器的编写、RAII 资源管理思想的实践,以及从裸指针迁移到智能指针的重构策略,帮助开发者编写安全无泄漏的现代 C++ 代码。

379

2026.04.23

堆和栈的区别
堆和栈的区别

堆和栈的区别:1、内存分配方式不同;2、大小不同;3、数据访问方式不同;4、数据的生命周期。本专题为大家提供堆和栈的区别的相关的文章、下载、课程内容,供大家免费下载体验。

6567

2023.07.18

堆和栈区别
堆和栈区别

堆(Heap)和栈(Stack)是计算机中两种常见的内存分配机制。它们在内存管理的方式、分配方式以及使用场景上有很大的区别。本文将详细介绍堆和栈的特点、区别以及各自的使用场景。php中文网给大家带来了相关的教程以及文章欢迎大家前来学习阅读。

2728

2023.08.10

堆和栈的区别
堆和栈的区别

堆和栈的区别:1、内存分配方式不同;2、大小不同;3、数据访问方式不同;4、数据的生命周期。本专题为大家提供堆和栈的区别的相关的文章、下载、课程内容,供大家免费下载体验。

6567

2023.07.18

Docker Desktop怎么设置端口映射
Docker Desktop怎么设置端口映射

本专题聚焦Docker Desktop容器端口映射与访问配置,整理从创建容器、设置端口绑定到验证本地服务访问的操作流程。针对端口被占用、映射配置错误、容器服务无法访问等情况,也提供相应的检查方向,方便用户完成端口配置。

0

2026.11.03

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
dev.java 官方:Learn Java
dev.java 官方:Learn Java

共0课时 | 0人学习

Java JDBC数据库连接官方教程
Java JDBC数据库连接官方教程

共0课时 | 0人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn