代码咖啡因的个人博客 代码咖啡因的个人博客

记录精彩的程序人生

目录
SpringBean生命周期
/    

SpringBean生命周期

Spring Bean生命周期线性执行顺序详解
(基于Spring 6.x版本,时间戳:2025年3月3日 01:17)


一、完整生命周期流程图

实例化 → 属性注入 → Aware回调 → BeanPostProcessor前置 → 初始化 → BeanPostProcessor后置 → 运行期 → 销毁


二、分阶段线性执行顺序

  1. 实例化阶段
    • 触发条件:容器启动或首次请求Bean时
    • 关键动作:
      ▸ 通过构造器/工厂方法创建对象实例
      ▸ 若实现InstantiationAwareBeanPostProcessor接口,优先执行postProcessBeforeInstantiation()(可跳过默认实例化)
  2. 属性注入阶段
    • 核心操作:
      ▸ 按类型/名称注入依赖(处理@Autowired、@Resource)
      ▸ 解析占位符和SpEL表达式(@Value)
    • 扩展点:
      ▸ InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation() (干预属性注入逻辑)
      ▸ InstantiationAwareBeanPostProcessor.postProcessProperties() (自定义属性处理)
  3. Aware接口回调
    • 执行顺序:
      ▸ BeanNameAware.setBeanName()
      ▸ BeanClassLoaderAware.setBeanClassLoader()
      ▸ BeanFactoryAware.setBeanFactory()
      ▸ 其他扩展Aware接口(如EnvironmentAware, ApplicationContextAware)
  4. BeanPostProcessor前置处理
    • 核心逻辑:
      ▸ 遍历所有BeanPostProcessor执行postProcessBeforeInitialization()
      ▸ 处理@PostConstruct注解方法(通过CommonAnnotationBeanPostProcessor实现)
  5. 初始化阶段
    • 执行顺序:
      ▸ InitializingBean.afterPropertiesSet()
      ▸ XML/注解声明的init-method(如@Bean(initMethod="customInit"))
  6. BeanPostProcessor后置处理
    • 关键作用:
      ▸ 执行postProcessAfterInitialization()
      ▸ 生成代理对象(如AOP在此阶段完成)
  7. 运行期阶段
    • 状态特征:
      ▸ Bean进入就绪状态,可被其他组件依赖
      ▸ 单例Bean驻留在IoC容器中,原型Bean每次请求新建实例
  8. 销毁阶段
    • 逆序执行逻辑:
      ▸ @PreDestroy注解方法
      ▸ DisposableBean.destroy()
      ▸ 自定义destroy-method
    • 触发条件:
      ▸ 容器关闭(ConfigurableApplicationContext.close() )
      ▸ 仅针对单例Bean执行

三、特殊场景执行差异

场景差异点
Prototype作用域Bean不执行销毁阶段(步骤8),容器不跟踪其生命周期
延迟初始化Bean步骤1-6在首次请求时触发,而非容器启动时
循环依赖通过三级缓存提前暴露半成品Bean,但初始化流程仍按完整顺序执行

四、调试与验证方法

  1. 日志观察:
    public class DebugBean implements InitializingBean, DisposableBean {  
        @PostConstruct  
        public void post() { System.out.println("@PostConstruct 执行"); }  
        @PreDestroy  
        public void pre() { System.out.println("@PreDestroy 执行"); }  
        @Override  
        public void afterPropertiesSet() { System.out.println("InitializingBean 回调"); }  
        @Override  
        public void destroy() { System.out.println("DisposableBean 回调"); }  
    }  
    
  2. 断点追踪:
    ▸ 在AbstractAutowireCapableBeanFactory的initializeBean()方法设置断点
    ▸ 监控BeanPostProcessor实现类的执行堆栈

五、设计启示

  1. 扩展点选择策略:
    • 优先使用@PostConstruct/@PreDestroy(JSR-250标准)
    • 避免同时实现InitializingBean和定义init-method(导致执行顺序混淆)
  2. 性能优化:
    • 减少BeanPostProcessor数量(影响所有Bean的初始化速度)
    • 对非必要Aware接口实现保持谨慎(增加耦合度)

总结:Spring Bean生命周期是一个严格线性但高度可扩展的流程,理解其执行顺序对解决依赖注入异常、优化启动性能、实现高级扩展功能(如自定义作用域)具有关键意义。