Spring容器启动:像开一家工厂一样理解源码

59 阅读2分钟

Spring容器启动:像开一家工厂一样理解源码

想象你要开一家汽车制造厂,Spring容器启动的过程就是工厂从图纸到量产的完整流程。我们以老式的ClassPathXmlApplicationContext为例,用工厂生产流水线来理解源码核心步骤。

一、项目立项(容器初始化)

ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");

这行代码相当于:

  1. 租厂房(创建容器实例)
  2. 拿到设计图纸(定位配置文件)
  3. 准备原料清单(创建BeanFactory)

就像老板拿到建厂批文时,首先确定工厂地址和基础架构。

二、车间建设(Bean定义加载)

refresh()方法是整个启动流程的核心,包含12个关键步骤:

  1. 准备车间图纸

    prepareRefresh(); // 初始化环境变量、校验配置文件
    

    相当于环保审批、消防验收等前置工作

  2. 组装生产线

    obtainFreshBeanFactory(); // 创建DefaultListableBeanFactory
    loadBeanDefinitions(beanFactory); // 加载Bean定义
    

    这里XML解析器像扫描仪一样,把标签转化为BeanDefinition对象,相当于:

    • 将每个零件(Bean)的规格书录入系统
    • 记录零件的生产方式(单例/原型)
    • 标注零件间的依赖关系(ref属性)

三、生产准备(Bean实例化)

  1. 零件预加工

    invokeBeanFactoryPostProcessors(); // 处理BeanFactory后置处理器
    

    就像在正式生产前:

    • 调整生产线参数(修改Bean定义)
    • 注册特殊零件(如@Configuration类)
  2. 安装质检设备

    registerBeanPostProcessors(); // 注册Bean后置处理器
    

    这些处理器就像质量检测员,在Bean的:

    • 初始化前(@PostConstruct)
    • 初始化后(AOP代理)
    • 销毁前(@PreDestroy) 进行拦截处理

四、正式投产(依赖注入)

  1. 启动生产线
    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创建]
      

五、工厂投产(完成启动)

  1. 开业庆典
    finishRefresh(); // 发布ContextRefreshedEvent事件
    
    就像工厂剪彩仪式,此时:
    • 所有单例Bean准备就绪
    • 可以监听事件执行启动任务
    • 对外提供完整服务能力

关键源码设计模式

  • 模板方法模式(refresh流程)
  • 观察者模式(事件监听)
  • 工厂方法模式(Bean创建)
  • 代理模式(AOP实现)

理解建议

  1. 调试时在AbstractApplicationContext的refresh()设断点
  2. 重点跟踪Bean生命周期关键节点
  3. 结合Spring官方时序图理解

当你能把BeanFactory想象成智能装配车间,把BeanPostProcessor看作质量检测机器人,复杂的源码就变成了生动的工厂生产纪录片。理解这个过程,下次遇到Bean创建异常时,你就能像车间主任排查生产线故障一样快速定位问题。