深入分析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扩展功能:如自定义注解解析、性能监控。
相关推荐
weixin_448771728 分钟前
Spring框架之ApplicationContext源码学习
java·学习·spring
白露与泡影16 分钟前
Spring AI Alibaba -- 文生图、文生音及向量化
java·人工智能·spring
滕州市燕猫虎计算机科技工作室个体工商户17 分钟前
Java,Java NIO,Java NIO2,Java AIO,AsynchronousServerSocketChannel
java·开发语言·nio·aio·nio2
学长毕设26 分钟前
基于springboot的社会志愿者管理系统-附源码
java·spring boot·后端
喵了几个咪27 分钟前
GoWind CMS 拆解:给 NL2SQL 上四把锁——智能问数的安全边界
开发语言·后端·安全·微服务·golang·gowind
木头科技42 分钟前
【AI 工程化第十六篇】Spring AI 多模态 RAG 实战:图片、扫描件、表格与图文证据链
java·人工智能·spring
用户8356290780511 小时前
Python 操作 Excel:创建数组公式与 R1C1 公式
后端·python
驭渊的小故事1 小时前
从 JVM 底层看泛型:泛型擦除、Signature 属性与 Super Type Token 模式
java·开发语言·jvm
菜鸟小杰子1 小时前
手动修改 Spring Boot 嵌套 JAR 包:大包小包隔离打包实战
java·jar
计算机编程-吉哥1 小时前
计算机毕业设计 基于 SpringBoot + Vue 的剧本杀系统 Java毕业设计【任务书、开题报告、中期报告、论文、源码】
java·vue.js·spring boot·毕业设计·课程设计·计算机毕业设计选题