面试知识库
极高 进阶

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
}
java

Spring 容器创建管理 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 按名称