⭐ *Spring IOC(控制反转)
1️⃣ IOC 是什么?(一句话)
IOC(控制反转)是把“对象创建与依赖管理”的控制权,从代码本身反转到 Spring 容器,由容器来统一创建、管理和装配 Bean。
这意味着:
- 你不再
new对象 - 不再手动管理依赖
- 只需要声明“我需要什么”,Spring 自动帮你准备好
2️⃣ DI(依赖注入)是什么?IOC 如何落地?
IOC 是思想,DI 是实现 IOC 的具体方式。
Spring 通过三种方式实现依赖注入:
✔ 构造器注入(推荐)
public UserService(UserRepository repo) { ... }
Spring 会:
查构造器 → 查参数类型 → 找到对应 Bean → 自动注入
✔ Setter 注入
✔ 字段注入(常用但不推荐)
构造器注入从 Spring 4.3 起,只有一个构造器时甚至不需要 @Autowired。
3️⃣ Spring 如何实现依赖注入?(最关键的部分)
当 Spring 要创建一个 Bean 时,它会:
1. 找到 Bean 的构造器
2. 查看构造器需要哪些参数(依赖)
3. 到 IOC 容器查找对应类型的 Bean 实例
4. 若依赖 Bean 尚未创建 → 先创建依赖 Bean
5. 使用构造器创建当前 Bean(依赖注入发生在此处)
6. 完成初始化,放入 IOC 容器中
核心点:
依赖注入发生在“创建 Bean 的瞬间”,不是创建后再塞进去。
4️⃣ IOC 容器到底是什么?它管理什么?
IOC容器是一个“智能工厂”,内部用一个大 Map 存 Bean:
Map<String, Object> singletonObjects
它负责:
- 创建 Bean(实例化)
- 注入依赖(DI)
- 管理生命周期(初始化、销毁)
- 处理代理(AOP、事务)
Spring 容器的两大核心实现:
| 容器类型 | 含义 |
|---|---|
| BeanFactory | 最基础的 IOC 工厂 |
| ApplicationContext | BeanFactory 的增强版,是我们实际使用的容器 |
我们日常说的“Spring IOC 容器”基本指 ApplicationContext。
5️⃣ 为什么这一行代码就自动注入了?
public UserService(UserRepository repo)
因为 Spring:
- 类只有一个构造器 → 默认用它进行依赖注入
- 构造器参数类型为
UserRepository - 容器中刚好存在该类型的 Bean
- Spring 自动匹配并注入
背后的执行者是:
AutowiredAnnotationBeanPostProcessor
它负责解析构造器、字段、setter,并完成注入。
6️⃣ IOC 的核心价值(面试会问)
✔ 解耦(最重要)
类之间不再主动 new 依赖对象,不再绑定具体实现。
✔ 更容易测试
可以随时替换依赖为 Mock 对象。
✔ 生命周期统一管理
由容器统一创建、销毁 Bean。
✔ 更容易扩展
只需要加一个实现类,Spring 就能自动装配。
7️⃣ IOC + DI 最简公式(面试必背)
IOC:对象创建与依赖管理反转给容器。
DI:容器在创建 Bean 时自动将其依赖注入进去。
ApplicationContext 是实际使用的 IOC 容器。
📌 最终浓缩版(你可以背这个):
IOC 是把控制权从代码反转给 Spring 容器,让容器负责 Bean 的创建、依赖注入和生命周期管理。
DI 是 IOC 的实现方式,通过构造器/Setter/字段让容器在创建 Bean 时自动注入依赖。
Spring 在创建 Bean 时解析构造器参数,找到依赖 Bean,从容器取出并注入进去。
IOC 容器本质是一个管理 Bean 的智能工厂,常用实现是 ApplicationContext。
🔹 一个手写 mini-IOC(20行代码)让你彻底理解原理
import java.lang.reflect.Constructor;
import java.util.HashMap;
import java.util.Map;
class MiniIOC {
private Map<Class<?>, Object> singletonObjects = new HashMap<>();
// 获取 Bean
public Object getBean(Class<?> clazz) throws Exception {
// 1. 单例池中已有 → 直接返回
if (singletonObjects.containsKey(clazz)) {
return singletonObjects.get(clazz);
}
// 2. 创建 Bean(核心逻辑)
// 找构造器
Constructor<?> constructor = clazz.getDeclaredConstructors()[0];
// 找参数类型
Class<?>[] paramTypes = constructor.getParameterTypes();
// 3. 递归创建依赖 Bean
Object[] dependencies = new Object[paramTypes.length];
for (int i = 0; i < paramTypes.length; i++) {
dependencies[i] = getBean(paramTypes[i]); // 递归调用
}
// 4. 调用构造器创建 Bean
Object bean = constructor.newInstance(dependencies);
// 5. 放入单例池
singletonObjects.put(clazz, bean);
return bean;
}
}
🎯 一句话本质总结(你可以背的)
IOC 本质就是:一个 Map 作为单例工厂 + 通过反射分析构造器参数,在创建 Bean 时递归创建依赖 Bean,实现自动注入。
⭐ 为什么要用 IOC?
IOC 的核心价值是解耦。
以前对象之间通过new互相依赖,耦合度高、难以替换实现、难测试、生命周期难管理。使用 IOC 后,Bean 的创建、依赖注入由容器统一管理,业务类只声明自己需要什么,从而实现:
- 解耦(不再自己 new)
- 易扩展(可随时替换实现)
- 易测试(能轻松注入 Mock)
- 易管理(生命周期、单例等)
IOC 是 Spring 能够模块化、可扩展、易维护的基础。
一句话总结:
IOC = 解耦 + 易扩展 + 易测试 + 统一管理。
Top comments (0)