极高 进阶
Spring-IoC原理#
一句话答案#
IoC 容器管理 Bean 的创建和依赖注入,控制反转让对象不再自己创建依赖而是由容器注入,降低耦合。
核心要点
IoC(Inversion of Control,控制反转):
- 传统方式:对象自己创建依赖对象(
new UserService()),控制权在调用方 - IoC:将创建对象的控制权交给容器,容器负责创建、管理、注入对象的依赖
DI(Dependency Injection,依赖注入)是 IoC 的具体实现方式:
// 传统(控制在自己)
class OrderService {
private UserService userService = new UserService(); // 自己 new
}
// IoC/DI(控制转移给容器)
@Service
class OrderService {
@Autowired
private UserService userService; // 容器注入,不需要自己 new
}javaSpring 容器创建管理 Bean 的流程:
1. 启动时扫描 @Component/@Service/@Repository/@Controller 注解的类
→ 生成 BeanDefinition(Bean 的元数据描述)
2. BeanDefinition 注册到 BeanDefinitionRegistry
3. 当需要 Bean 时(非懒加载单例在容器刷新时、懒加载在首次使用时):
→ 按 [Bean生命周期](/topics/spring/Bean生命周期) 创建 Bean
4. 单例 Bean 创建后存入 singletonObjects(一级缓存)
后续同名 Bean 请求直接从缓存返回
5. Bean 销毁:容器关闭时,调用 DisposableBean.destroy() 等销毁方法plaintext面试回答(2分钟版)
IoC即控制反转,核心思想是把对象创建和依赖管理的控制权从应用代码转移给容器。传统方式是对象内部直接new依赖,耦合度高且难以测试;IoC模式下对象只声明需要什么依赖,由Spring容器负责创建和注入。DI依赖注入是IoC的具体实现方式,Spring支持三种注入方式:构造器注入、setter注入和字段注入,官方推荐构造器注入因为它保证依赖不可变且必须满足。容器启动时的工作流程是:先扫描@Component、@Service等注解的类生成BeanDefinition元数据,注册到BeanDefinitionRegistry中,然后按照Bean生命周期创建实例并完成依赖注入,单例Bean创建后存入singletonObjects一级缓存供后续直接获取。@Autowired默认按类型注入,当存在多个同类型实现时需要配合@Qualifier按名称指定。BeanFactory是IoC容器的根接口提供基本的Bean管理能力,ApplicationContext在其基础上扩展了事件发布、国际化、AOP集成等企业级功能,实际开发中用的都是ApplicationContext。
追问与易错
追问方向:
- “IoC 和 DI 的关系?”→ IoC 是控制反转的设计思想(把对象创建控制权交给容器),DI 依赖注入是 IoC 的具体实现方式(容器在运行时将依赖注入到对象中)
- “@Autowired 按什么注入?有多个实现类怎么办?”→ 默认按类型(byType)注入,存在多个同类型 Bean 时需配合 @Qualifier 按名称指定,或在实现类上加 @Primary 标记优先级
- “为什么推荐构造器注入?”→ 依赖声明为 final 保证不可变、构造时强制满足所有依赖不会出现空指针、方便单元测试 mock 注入、避免循环依赖(构造器循环依赖会直接报错暴露设计问题)
易错点:
- ❌ “IoC 就是 DI”——IoC 是控制反转(更广),DI 只是其中一种实现
- ❌ “@Autowired 按名称注入”——默认按类型,只有类型冲突时配合 @Qualifier 按名称