深入分析spring容器中Bean的生命周期

知其然要知其所以然,探索每一个知识点背后的意义,你知道的越多,你不知道的越多,一起学习,一起进步,如果文章感觉对您有用的话,关注、收藏、点赞,有困惑的地方请评论,我们一起交流!


Spring Bean的生命周期是一个由多个阶段组成的复杂过程,涉及实例化、依赖注入、初始化及销毁等步骤。以下是Bean生命周期的详细分析:

1. Bean生命周期概览

Spring Bean的生命周期大致分为以下阶段:

  1. 实例化(Instantiation)
  2. 属性赋值(Population)
  3. Aware接口回调
  4. BeanPostProcessor前置处理
  5. 初始化方法(Initialization)
  6. BeanPostProcessor后置处理
  7. Bean就绪(Ready)
  8. 销毁(Destruction)

2. 详细生命周期流程

2.1 实例化(Instantiation)

  • 触发时机:容器根据Bean定义(如XML配置、注解或Java Config)创建Bean实例。
  • 实现方式
    • 通过构造函数(默认无参构造或指定构造器)。
    • 通过静态工厂方法或实例工厂方法。
  • 关键扩展点
    • InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation
      在实例化前拦截,可返回自定义对象替代默认实例化逻辑(如生成代理对象)。

2.2 属性赋值(Population)

  • 依赖注入
    • 通过Setter方法、字段注入(@Autowired)或构造器注入完成属性填充。
    • 处理@Value注解,注入配置文件中的值。
  • 关键扩展点
    • InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation
      实例化后、属性注入前执行,返回false可阻止属性注入。
    • InstantiationAwareBeanPostProcessor.postProcessProperties
      自定义属性注入逻辑(如解析自定义注解)。

2.3 Aware接口回调

Bean通过实现Aware接口获取容器基础设施信息:

  • 常见Aware接口
    • BeanNameAware:设置Bean的名称。
    • BeanFactoryAware:设置Bean所属的BeanFactory。
    • ApplicationContextAware:设置ApplicationContext(如获取其他Bean)。
  • 执行顺序
    在属性注入之后、初始化方法之前调用。

2.4 BeanPostProcessor前置处理

  • 方法
    BeanPostProcessor.postProcessBeforeInitialization
  • 作用
    在初始化方法前对Bean进行增强(如修改属性值)。
  • 典型应用
    @PostConstruct注解的处理(通过CommonAnnotationBeanPostProcessor)。

2.5 初始化方法(Initialization)

  • 执行顺序
    1. @PostConstruct注解标记的方法。
    2. InitializingBean.afterPropertiesSet()方法。
    3. XML或@Bean(initMethod = "init")指定的自定义初始化方法。
  • 特点
    所有依赖已注入,Bean处于可用状态前的最后准备。

2.6 BeanPostProcessor后置处理

  • 方法
    BeanPostProcessor.postProcessAfterInitialization
  • 作用
    在初始化完成后对Bean进行最终处理(如生成AOP代理)。
  • 典型应用
    AbstractAutoProxyCreator创建动态代理对象。

2.7 Bean就绪(Ready)

  • Bean被放入单例缓存池(singletonObjects)。
  • 可被其他Bean依赖或通过容器获取。

2.8 销毁(Destruction)

  • 触发条件 :容器关闭(如调用ConfigurableApplicationContext.close())。
  • 执行顺序
    1. @PreDestroy注解标记的方法。
    2. DisposableBean.destroy()方法。
    3. XML或@Bean(destroyMethod = "cleanup")指定的自定义销毁方法。
  • 作用:释放资源(如关闭数据库连接)。

3. 扩展点与核心接口

3.1 BeanPostProcessor

  • 功能:在Bean初始化前后插入自定义逻辑。
  • 典型实现
    • AutowiredAnnotationBeanPostProcessor:处理@Autowired@Value
    • CommonAnnotationBeanPostProcessor:处理@PostConstruct@PreDestroy
    • AbstractAutoProxyCreator:生成AOP代理。

3.2 InstantiationAwareBeanPostProcessor

  • 功能:干预实例化与属性注入过程。
  • 关键方法
    • postProcessBeforeInstantiation:替代默认实例化。
    • postProcessAfterInstantiation:控制是否注入属性。
    • postProcessProperties:自定义属性注入。

3.3 Lifecycle接口

  • 方法
    • start():在上下文刷新后调用(需显式启动上下文)。
    • stop():在上下文关闭时调用。
  • 用途:管理后台线程或长周期任务。

4. 生命周期流程图

plaintext 复制代码
1. 实例化Bean
   │
   ↓
2. 属性注入(依赖注入)
   │
   ↓
3. Aware接口回调(BeanNameAware → BeanFactoryAware → ApplicationContextAware)
   │
   ↓
4. BeanPostProcessor.postProcessBeforeInitialization
   │
   ↓
5. 初始化方法(@PostConstruct → InitializingBean → init-method)
   │
   ↓
6. BeanPostProcessor.postProcessAfterInitialization(生成代理对象)
   │
   ↓
7. Bean就绪(加入单例池)
   │
   ↓
8. 容器关闭时销毁(@PreDestroy → DisposableBean → destroy-method)

5. 特殊场景分析

5.1 循环依赖

  • 支持场景:单例Bean通过Setter/字段注入的循环依赖。
  • 解决机制 :三级缓存(singletonFactories提前暴露半成品Bean)。

5.2 原型作用域(Prototype)

  • 特点:每次请求创建新实例,不执行销毁方法。
  • 生命周期:实例化 → 属性注入 → 初始化 → 使用 → 被GC回收。

5.3 AOP代理

  • 代理时机 :在postProcessAfterInitialization阶段生成代理对象。
  • 影响 :外部调用通过代理对象进行,但生命周期方法(如@PostConstruct)在原始Bean执行。

6. 建议

  1. 优先使用构造器注入:明确依赖关系,避免循环依赖。
  2. 避免在初始化方法中调用其他Bean:防止未完全初始化的依赖导致问题。
  3. 谨慎使用@PostConstruct@PreDestroy :确保方法无参数且返回void
  4. 利用BeanPostProcessor扩展功能:如自定义注解解析、性能监控。
相关推荐
xiaolingting43 分钟前
Java 二叉树非递归遍历核心实现
java··二叉树非递归遍历
嘵奇44 分钟前
深入解析 Java 8 Function 接口:函数式编程的核心工具
java·开发语言
东方靖岚2 小时前
R语言的数据库交互
开发语言·后端·golang
一路向北North3 小时前
IDEA加载项目时依赖无法更新
java·ide·intellij-idea
振鹏Dong4 小时前
超大规模数据场景(思路)——面试高频算法题目
算法·面试
uhakadotcom4 小时前
Python 与 ClickHouse Connect 集成:基础知识和实践
算法·面试·github
uhakadotcom4 小时前
Python 量化计算入门:基础库和实用案例
后端·算法·面试
小萌新上大分4 小时前
SpringCloudGateWay
java·开发语言·后端·springcloud·springgateway·cloudalibaba·gateway网关
uhakadotcom4 小时前
使用Python获取Google Trends数据:2025年详细指南
后端·面试·github
uhakadotcom4 小时前
使用 Python 与 Google Cloud Bigtable 进行交互
后端·面试·github