Spring容器启动:像开一家工厂一样理解源码
想象你要开一家汽车制造厂,Spring容器启动的过程就是工厂从图纸到量产的完整流程。我们以老式的ClassPathXmlApplicationContext为例,用工厂生产流水线来理解源码核心步骤。
一、项目立项(容器初始化)
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
这行代码相当于:
- 租厂房(创建容器实例)
- 拿到设计图纸(定位配置文件)
- 准备原料清单(创建BeanFactory)
就像老板拿到建厂批文时,首先确定工厂地址和基础架构。
二、车间建设(Bean定义加载)
refresh()方法是整个启动流程的核心,包含12个关键步骤:
-
准备车间图纸
prepareRefresh(); // 初始化环境变量、校验配置文件相当于环保审批、消防验收等前置工作
-
组装生产线
obtainFreshBeanFactory(); // 创建DefaultListableBeanFactory loadBeanDefinitions(beanFactory); // 加载Bean定义这里XML解析器像扫描仪一样,把标签转化为BeanDefinition对象,相当于:
- 将每个零件(Bean)的规格书录入系统
- 记录零件的生产方式(单例/原型)
- 标注零件间的依赖关系(ref属性)
三、生产准备(Bean实例化)
-
零件预加工
invokeBeanFactoryPostProcessors(); // 处理BeanFactory后置处理器就像在正式生产前:
- 调整生产线参数(修改Bean定义)
- 注册特殊零件(如@Configuration类)
-
安装质检设备
registerBeanPostProcessors(); // 注册Bean后置处理器这些处理器就像质量检测员,在Bean的:
- 初始化前(@PostConstruct)
- 初始化后(AOP代理)
- 销毁前(@PreDestroy) 进行拦截处理
四、正式投产(依赖注入)
- 启动生产线
这里采用智能装配策略:finishBeanFactoryInitialization(); // 实例化所有单例Bean- 构造器注入:先组装车架,再装发动机
- 三级缓存解决循环依赖:
graph LR A[创建A对象] --> B[提前暴露工厂放入三级缓存] B --> C[发现依赖B] C --> D[创建B对象] D --> E[提前暴露B工厂] E --> F[B需要注入A] F --> G[从三级缓存拿到A工厂创建完整A] G --> H[完成B创建] H --> I[完成A创建]
五、工厂投产(完成启动)
- 开业庆典
就像工厂剪彩仪式,此时:finishRefresh(); // 发布ContextRefreshedEvent事件- 所有单例Bean准备就绪
- 可以监听事件执行启动任务
- 对外提供完整服务能力
关键源码设计模式:
- 模板方法模式(refresh流程)
- 观察者模式(事件监听)
- 工厂方法模式(Bean创建)
- 代理模式(AOP实现)
理解建议:
- 调试时在AbstractApplicationContext的refresh()设断点
- 重点跟踪Bean生命周期关键节点
- 结合Spring官方时序图理解
当你能把BeanFactory想象成智能装配车间,把BeanPostProcessor看作质量检测机器人,复杂的源码就变成了生动的工厂生产纪录片。理解这个过程,下次遇到Bean创建异常时,你就能像车间主任排查生产线故障一样快速定位问题。