Spring IoC容器原理

通俗易懂!Spring IoC 容器原理一次讲透(2025 面试最爱画的那张图,背完直接满分)

一句话记住 IoC 容器是干嘛的:

Spring IoC 容器就是一个超级智能的“对象工厂 + 对象仓库”,你只管告诉它“我要什么”,它就负责造好、管好、给你用,你再也不用自己 new 对象了!

IoC 容器到底长什么样?(面试必画图)

┌─────────────────────────────────────────────┐
│              ApplicationContext              │ ← 你平时用的就是它
│   ┌─────────────────────────────────────┐   │
│   │            BeanFactory                  │ ← 底层最原始接口
│   │   ┌────────────────────────────────┐    │
│   │   │  1. BeanDefinition(设计图)      │    │
│   │   │  2. BeanDefinitionReader(读图纸)│    │
│   │   │  3. BeanFactoryPostProcessor      │    │ ← 修改图纸(@ConfigurationProperties)
│   │   │  4. BeanPostProcessor             │    │ ← 造之前/造之后插手(@Autowired、AOP)
│   │   │  5. InstantiationAwareBeanPostProcessor│← 最早插手(解决循环依赖)
│   │   │  6. Singleton Bean Cache(三级缓存)   │ ← 解决循环依赖核心
│   │   └────────────────────────────────┐    │
└─────────────────────────────────────────────┘

Spring 启动时到底干了 8 件事(经典流程,背下来就能手画)

  1. 准备容器:new AnnotationConfigApplicationContext(AppConfig.class)
  2. 读取配置:扫描 @ComponentScan 包下所有类,找到带 @Component 的
  3. 解析成 BeanDefinition(一张张“设计图”):类名、scope、是否懒加载、依赖哪些类…
  4. BeanFactoryPostProcessor 执行:比如 ConfigurationPropertiesBindingPostProcessor(把 yml 配置绑到 @ConfigurationProperties 类)
  5. 提前实例化所有单例 Bean(refresh() → finishBeanFactoryInitialization())
  6. 造 Bean 过程(doCreateBean):
  • 实例化(new 对象)→ 放进三级缓存
  • 属性填充(@Autowired 注入)
  • 初始化(调用 @PostConstruct、InitializingBean)
  • 放进一级缓存(完成)
  1. BeanPostProcessor 前后插手:
  • 前:可以替换对象(代理、@Autowired 注入)
  • 后:初始化后做额外事(AOP 代理、@Async)
  1. 容器启动完成,你 @Autowired 拿到的都是现成的对象

三级缓存(解决循环依赖的终极秘密!面试必问)

// 3个 Map,记住名字就行
singletonObjects           (一级缓存) → 完全初始化好的 Bean
earlySingletonObjects      (二级缓存) → 正在创建但还没填完属性的半成品
singletonFactories         (三级缓存) → 工厂(放 Lambda,能提前暴露半成品)

循环依赖例子:A 依赖 B,B 依赖 A

  1. 造 A → 实例化 → 放三级缓存(能提前拿到半成品引用)
  2. 造 B → 发现需要 A → 从三级缓存拿到 A 的半成品引用
  3. B 造完 → A 继续填充 B 属性 → A 完成 → 升级到一级缓存

记住一句话:三级缓存的核心不是“三个 Map”,而是“提前暴露一个能创建对象的 Lambda”,让别人能拿到半成品引用!

两个最核心接口(面试必问区别)

接口特点实际项目用吗?
BeanFactory最底层接口,懒加载,只管创建 Bean基本不用
ApplicationContext继承 BeanFactory + 事件发布、国际化、资源加载、AOP…100% 用这个

一句话:BeanFactory 是工厂,ApplicationContext 是带物业的高级小区!

2025 面试最爱问的 6 个问题 + 标准答案

  1. Spring 容器启动过程?
    → 扫描 → BeanDefinition → BeanFactoryPostProcessor → 实例化单例 → BeanPostProcessor → 完成
  2. 三级缓存怎么解决循环依赖?
    → 提前暴露 ObjectFactory,半成品就能被别人引用,构造后注入完成
  3. 为什么不能用两级缓存?
    → 两级缓存只能解决“引用”,不能解决 AOP 代理后的对象不一致问题,三级缓存 + ObjectFactory 才能保证代理对象一致
  4. @Autowired 是怎么注入的?
    → AutowiredAnnotationBeanPostProcessor(一个 BeanPostProcessor)在属性填充阶段解析 @Autowired 并注入
  5. @PostConstruct 什么时候执行?
    → 初始化阶段,调用 invokeInitMethods() 时执行,顺序:@PostConstruct → InitializingBean → init-method
  6. 容器里 Bean 是线程安全的吗?
    → 看你自己写的代码!容器不保证线程安全,单例 Bean 默认全局共享,要么 stateless,要么加锁

背完这张图 + 这 8 个步骤 + 三级缓存原理,
面试官问 IoC 容器原理,你 3 分钟手画 + 讲完,直接给“原理掌握非常扎实”评价!

一句话总结:
Spring IoC 容器 = 设计图(BeanDefinition) + 工厂(BeanFactory) + 各种钩子(PostProcessor) + 三级缓存魔法,
让你彻底摆脱 new 和硬编码,优雅写企业级代码!冲就完了!

文章已创建 3017

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

相关文章

开始在上面输入您的搜索词,然后按回车进行搜索。按ESC取消。

返回顶部