Spring IoC 与 DI:从"手动装配"到"容器托管"的思维转变
本文是 Java SpringBoot 多人协作平台项目实战系列第 3 课的学习笔记整理,聚焦于 Spring 框架的核心设计思想:IoC(控制反转)与 DI(依赖注入)。
一、Spring 是什么?
Spring 是 Java 生态中 IoC 容器的事实标准。
你可能会问:为什么需要 Spring?直接写 Java 不行吗?
当然可以——但仅限于项目规模较小的时候。随着项目不断膨胀,服务与服务之间的依赖关系会呈指数级增长,手工维护这些关系将变得极其繁琐且容易出错。这正是 Spring 这类自动化框架存在的意义:接管对象的创建与装配,让开发者专注于业务逻辑本身。
二、软件工程的基本思路:模块化
在着手解决具体问题之前,软件工程有一条根本原则:分而治之。
- 将一个大型项目拆分为多个独立模块,模块之间通过约定好的接口进行通信;
- 模块之间存在依赖关系(A 模块需要 B 模块提供的能力才能完成工作);
- 复杂模块可以进一步拆分为子模块。
在 Java 的历史语境中,承担"完成具体工作"职责的对象有一个约定俗成的名字——Bean。
三、依赖关系带来的问题
以一个电商场景为例,我们有两个服务:
UserService:负责用户相关的操作;OrderService:负责下单流程,下单时需要获取用户信息。
package hello.service;
public class OrderService {
private UserService userService;
public void placeOrder() {
userService.getUserId(1);
// 执行下单逻辑
}
}
在这段代码中,OrderService 依赖 UserService,意味着:
必须先创建 UserService,再创建 OrderService,否则 OrderService 无法正常工作。
两个服务时,这种依赖关系尚在掌控之中。但当一个真实项目中存在几十甚至上百个 Bean,且它们之间形成复杂的依赖网络时,手工维护创建顺序和装配逻辑将变成一场灾难。
四、Spring IoC 容器:把控制权交出去
Spring 给出的解决方案是:IoC 容器(Inversion of Control Container)。
IoC 是什么?
IoC,即控制反转(Inversion of Control) ,是一种设计原则。
- 没有 IoC 时:开发者必须自己理清所有 Bean 的依赖关系,手动按顺序创建并组装成一个完整的应用;
- 有了 IoC 容器:开发者只需声明"A 依赖 B,B 依赖 C",容器会自动分析依赖图,按正确顺序创建并装配好所有 Bean。
换句话说,对象的创建和生命周期管理的"控制权",从开发者手中转移到了容器手中,这就是"控制反转"的含义。
Spring 容器就是这样一个 IoC 容器,里面维护着应用所需的全部 Bean 实例。
五、DI:IoC 的落地实现
DI 是什么?
DI,即依赖注入(Dependency Injection) ,是实现 IoC 最主流的具体技术手段。
其核心逻辑非常直接:
若 Bean A 依赖 Bean B,Spring 容器会在创建 A 时,自动将 B 的实例注入到 A 中,无需开发者手动传递。
IoC 与 DI 的关系
| 概念 | 类型 | 说明 |
|---|---|---|
| IoC(控制反转) | 设计思想 / 原则 | 描述"谁来负责管理对象"的问题 |
| DI(依赖注入) | 实现技术 / 手段 | IoC 思想最主流的落地方式 |
一句话总结:IoC 是目标,DI 是达成目标的方式。
六、小结
| 概念 | 核心要点 |
|---|---|
| Spring | Java IoC 容器的事实标准,解决大规模 Bean 管理问题 |
| Bean | Java 中承担具体业务职责的对象 |
| 依赖关系 | A 服务必须借助 B 服务才能完成工作,则 A 依赖 B |
| IoC | 将对象创建与装配的控制权交给容器,而非开发者手动管理 |
| DI | 容器在构建 Bean 时,自动将其所依赖的 Bean 注入进来 |
理解 IoC 与 DI,是真正掌握 Spring 框架的第一步。后续课程中,我们将看到这些理念如何在 SpringBoot 项目里通过注解(如 @Autowired、@Component、@Service)得到优雅的体现。
系列课程:Java SpringBoot 多人协作平台实战 · 第三节