当前位置: 首页 > news >正文

Spring IoC容器原理深度解析:源码级剖析(通俗易懂版)

Spring IoC容器原理深度解析:源码级剖析(通俗易懂版)

  • 一、核心思想:好莱坞原则
  • 二、容器核心架构
  • 三、核心实现原理(源码级解析)
    • 1. 存储容器:BeanDefinition注册中心
    • 2. 启动流程:容器初始化(refresh方法)
    • 3. Bean创建流程(源码级流程)
    • 4. 解决循环依赖(三级缓存机制)
  • 四、依赖注入的三种方式
    • 1. 字段注入(最常用)
    • 2. 构造器注入(推荐)
    • 3. Setter方法注入
  • 五、Bean生命周期管理(关键扩展点)
  • 六、容器实现的精华原理
    • 1. 配置解析过程(配置 → BeanDefinition)
    • 2. 单例Bean的延迟初始化(源码级)
    • 3. 动态代理如何融入容器
  • 七、通俗总结:IoC容器的本质

一、核心思想:好莱坞原则

“Don’t call us, we’ll call you” - 你不用找对象,对象会来找你
IoC(控制反转)的本质是将对象的创建与依赖关系的控制权从程序员手中转移到容器。想象你点外卖(需要对象)时:

  • 传统方式:你自己买菜、切菜、烹饪(new Object())
  • IoC方式:你只需下单(声明需求),外卖平台(容器)自动配送到家

二、容器核心架构

«interface»
BeanFactory
+getBean(String name) : Object
+isSingleton(String name) : boolean
«interface»
ApplicationContext
+refresh() : void
DefaultListableBeanFactory
-beanDefinitionMap Map
+registerBeanDefinition()
+preInstantiateSingletons()

三、核心实现原理(源码级解析)

1. 存储容器:BeanDefinition注册中心

// DefaultListableBeanFactory.java
private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(256);

每个Bean的定义(BeanDefinition)包括:

  • 类路径(className)
  • 作用域(singleton/prototype)
  • 依赖关系(dependsOn)
  • 初始化/销毁方法

2. 启动流程:容器初始化(refresh方法)

// AbstractApplicationContext.java
public void refresh() {// 1. 创建并配置Bean工厂ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();// 2. 加载Bean定义loadBeanDefinitions(beanFactory);// 3. 注册Bean后处理器registerBeanPostProcessors(beanFactory);// 4. 初始化单例Bean (关键步骤!)finishBeanFactoryInitialization(beanFactory);
}

3. Bean创建流程(源码级流程)

IoC容器 BeanFactory BeanProcessor Bean 1. getBean("userService") 2. createBeanInstance() 3. populateProperties() 4. postProcessBeforeInitialization() 5. invokeInitMethods() 6. postProcessAfterInitialization() 7. 返回完整Bean IoC容器 BeanFactory BeanProcessor Bean

4. 解决循环依赖(三级缓存机制)

// DefaultSingletonBeanRegistry.java
// 一级缓存:成品Bean
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256); // 二级缓存:半成品Bean(提前暴露)
private final Map<String, Object> earlySingletonObjects = new HashMap<>(16);  // 三级缓存:Bean工厂(解决代理问题)
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);

处理流程:

  1. UserService创建时将自己放入三级缓存(ObjectFactory)
  2. 填充依赖时发现需要RoleService
  3. 创建RoleService时发现需要UserService
  4. 从三级缓存获取UserService的早期代理
  5. 完成RoleService创建,并注入UserService

四、依赖注入的三种方式

1. 字段注入(最常用)

public class UserService {@Autowired private UserDao userDao; // 自动注入
}

源码实现:

// AutowiredAnnotationBeanPostProcessor.java
public PropertyValues postProcessPropertyValues(PropertyValues pvs, Object bean, String beanName) {// 反射获取@Autowired字段InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass());// 执行注入metadata.inject(bean, beanName, pvs);
}

2. 构造器注入(推荐)

public class OrderService {private PaymentService paymentService;@Autowiredpublic OrderService(PaymentService paymentService) {this.paymentService = paymentService;}
}

3. Setter方法注入

public class ProductService {private StorageService storageService;@Autowiredpublic void setStorageService(StorageService storageService) {this.storageService = storageService;}
}

五、Bean生命周期管理(关键扩展点)

实例化Bean
填充属性
调用Aware方法
应用前置处理器
调用初始化方法
应用后置处理器
准备就绪
容器关闭
调用销毁方法

核心接口:

  1. BeanPostProcessor:Bean初始化前后回调
    • postProcessBeforeInitialization()
    • postProcessAfterInitialization()
  2. BeanFactoryPostProcessor:Bean定义解析完成后回调
  3. InitializingBean/DisposableBean:初始化/销毁接口

六、容器实现的精华原理

1. 配置解析过程(配置 → BeanDefinition)

配置文件/注解
BeanDefinitionReader
BeanDefinition
BeanDefinition注册中心

2. 单例Bean的延迟初始化(源码级)

// DefaultListableBeanFactory.java
public void preInstantiateSingletons() {List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);for (String beanName : beanNames) {// 只初始化非懒加载的单例Beanif (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {getBean(beanName); // 触发创建}}
}

3. 动态代理如何融入容器

// AbstractAutoProxyCreator.java(AOP实现核心)
public Object postProcessAfterInitialization(Object bean, String beanName) {if (shouldProxy(bean.getClass())) {// 创建代理对象return wrapIfNecessary(bean, beanName);}return bean;
}

七、通俗总结:IoC容器的本质

想象Spring容器是个"智能机器人管家"

  1. 你把电器说明书(Bean定义)交给它:
  • “这是个电饭煲类,插电才能用(依赖)”
  1. 管家收集所有说明书建档案库(BeanDefinitionMap)
  2. 当你喊"我要做饭"(getBean(“riceCooker”)):
    • 它先查说明书 → 找到电饭煲类
    • 发现需要电源(依赖)→ 找到"电源"插头
    • 组装好电饭煲(实例化)→ 接好电源线(依赖注入)
    • 按下启动按钮(初始化方法)
  3. 成品电饭煲送到你手里直接使用
  4. 用完喊"收工"(context.close())→ 管家自动断电(销毁)
    整个过程你只需"声明需求",完全不用操心如何组装对象、处理依赖关系,这就是IoC容器的精妙之处!

相关文章:

  • 分库分表之数据库分片分类
  • Android Framework 调用栈
  • 【力扣每日一题】划分数组并满足最大差限制
  • cloudera manager 页面启动nodemanager失败,后端没有启动 8040
  • JWT基础概念详解
  • MySQL常用函数详解之流程函数
  • 解决你的100个问题——梦想
  • 硬编码(Reg/Opcode 和 SIB)
  • moduo之线程Thread
  • 为什么会出现 make 工程管理器?它到底能做什么?
  • [Linux_core] “虚拟文件” | procfs | devfs | 上下文
  • 前端大文件分片上传+后端(node)接收分片并合并
  • Android 网络请求的选择逻辑(Connectivity Modules)
  • 深入解析 MySQL 并发控制:读写锁、锁粒度与高级优化
  • 数据库(考前两天版本)
  • 李沐动手深度学习(pycharm中运行笔记)——11.模型选择+过拟合欠拟合
  • SQL关键字三分钟入门:UNION 与 UNION ALL —— 数据合并全攻略
  • RKNN开发环境搭建3-RKNN Model Zoo 板载部署以Whisper为例
  • pyqt 简单条码系统
  • OpenStack入门
  • 微信官方网站网址/企业为何选择网站推广外包?
  • 东莞营销网站建设哪个平台好/关键词林俊杰mp3在线听
  • 深圳沙井做网站/网络营销个人感悟小结
  • 广西疫情最新消息今天/网站优化一年多少钱
  • 溧水区住房和城乡建设厅网站/seo服务公司
  • 辽宁省网站建设/seo网络推广是干嘛的