外观
一句话答案
IoC 容器管理 Bean 的创建和依赖注入,控制反转让对象不再自己创建依赖而是由容器注入,降低耦合。
核心要点
IoC(Inversion of Control,控制反转):
- 传统方式:对象自己创建依赖对象(
new UserService()),控制权在调用方 - IoC:将创建对象的控制权交给容器,容器负责创建、管理、注入对象的依赖
DI(Dependency Injection,依赖注入)是 IoC 的具体实现方式:
java
// 传统(控制在自己)
class OrderService {
private UserService userService = new UserService(); // 自己 new
}
// IoC/DI(控制转移给容器)
@Service
class OrderService {
@Autowired
private UserService userService; // 容器注入,不需要自己 new
}Spring 容器创建管理 Bean 的流程:
1. 启动时扫描 @Component/@Service/@Repository/@Controller 注解的类
→ 生成 BeanDefinition(Bean 的元数据描述)
2. BeanDefinition 注册到 BeanDefinitionRegistry
3. 当需要 Bean 时(非懒加载单例在容器刷新时、懒加载在首次使用时):
→ 按 Bean 生命周期创建 Bean(见 Q1)
4. 单例 Bean 创建后存入 singletonObjects(一级缓存)
后续同名 Bean 请求直接从缓存返回
5. Bean 销毁:容器关闭时,调用 DisposableBean.destroy() 等销毁方法追问与易错
追问方向:
- IoC 和 DI 的关系?(IoC 是思想,DI 是实现方式)
- @Autowired 按什么注入?有多个实现类怎么办?(按类型→@Qualifier 按名称)
- 为什么推荐构造器注入?(不可变/必须依赖/方便测试)
易错点:
- ❌ "IoC 就是 DI"——IoC 是控制反转(更广),DI 只是其中一种实现
- ❌ "@Autowired 按名称注入"——默认按类型,只有类型冲突时配合 @Qualifier 按名称
💡 记忆锚点
IoC = 从"自己做饭"变成"点外卖":你不再new依赖,而是告诉容器你要什么,容器负责创建和送达(依赖注入)。IoC是思想(控制反转),DI是实现(依赖注入),@Autowired默认按类型注入,类型冲突加@Qualifier按名称。