当前位置: 首页 > news >正文

Spring Bean的生命周期

以下是Spring Bean生命周期的详细步骤总结,按执行顺序排列:


1. 实例化(Instantiation)

  • 触发时机:容器启动时(单例Bean)或每次请求时(原型Bean)
  • 方式
    • 构造器反射调用(默认)
    • 工厂方法(静态工厂/实例工厂)

2. 属性赋值(Populate Properties)

  • 依赖注入:通过Setter方法、字段注入或构造器注入完成属性赋值
  • 特殊注入@Autowired@Resource@Value等注解处理

3. Aware接口回调

  • BeanNameAware:注入Bean的ID
  • BeanFactoryAware:注入BeanFactory实例
  • ApplicationContextAware:注入ApplicationContext(注意:在BeanFactory环境下不生效
  • 其他Aware:如EnvironmentAware、ResourceLoaderAware等

4. BeanPostProcessor前置处理

  • 方法postProcessBeforeInitialization()
  • 典型应用
    • 生成代理对象(如AOP)
    • 修改Bean属性(如加密字段解密)

5. 初始化(Initialization)

  • InitializingBean接口:执行afterPropertiesSet()
  • 自定义初始化方法
    • XML配置的init-method
    • @PostConstruct注解标注的方法(最先执行

6. BeanPostProcessor后置处理

  • 方法postProcessAfterInitialization()
  • 典型应用
    • 最终代理包装(如事务增强)
    • 缓存预加载

7. Bean就绪可用

  • 此时Bean已进入应用上下文,可被其他组件依赖使用

8. 销毁(Destruction)

  • 触发条件:容器关闭时(仅单例Bean)
  • 执行顺序
    1. @PreDestroy注解方法
    2. DisposableBean接口的destroy()
    3. XML配置的destroy-method
  • 原型Bean:不会执行销毁方法,需手动清理

完整流程图


特殊场景说明

  1. 循环依赖
    • 三级缓存解决单例Bean的构造器循环依赖
    • 原型Bean的循环依赖直接报错
  2. 作用域差异
    • 单例Bean:完整生命周期
    • 原型Bean:只到初始化阶段,不执行销毁
  3. FactoryBean
    • 通过getObject()创建实际Bean
    • 生命周期独立于FactoryBean本身

监控生命周期的三种方式

  1. 接口方式
public class DemoBean implements InitializingBean, DisposableBean {@Overridepublic void afterPropertiesSet() { /* 初始化 */ }@Overridepublic void destroy() { /* 销毁 */ }
}
  1. 注解方式
public class DemoBean {@PostConstructpublic void init() { /* 初始化 */ }@PreDestroypublic void cleanup() { /* 销毁 */ }
}
  1. XML配置方式
<bean class="com.example.DemoBean" init-method="customInit" destroy-method="customDestroy"/>

性能优化提示

  • 尽量避免在生命周期方法中执行耗时操作
  • 合理使用@Lazy延迟初始化降低启动耗时
  • 原型Bean频繁创建/销毁时注意资源释放

掌握Bean生命周期机制,可以更精准地控制组件初始化顺序、资源管理,并实现高级定制功能(如动态代理增强)。

http://www.xdnf.cn/news/612685.html

相关文章:

  • 深度学习模型可视化:Netron的安装和使用
  • 深度学习-162-DeepSeek之调用远程大模型API接口参数结构分析
  • Socket 的两个不同含义:硬件 CPU Socket 和 网络 Socket 的区别
  • MySQL——复合查询表的内外连
  • 第十节第七部分:Arrays类、自定义排序规则Comparable、自定义比较器Comparator
  • PHP简介
  • DEEPSEEK + 其他工具的玩法
  • 深入剖析Go并发性能瓶颈:pprof实战指南
  • 力扣面试150题--路径总和
  • Stable Diffusion底模对应的VAE推荐
  • Docker端口映射与容器互联
  • 基于JSP+MySQL 服装销售系统
  • 今日学习:AOP数据脱敏|线程池|方法引用的实例|背包(0-1)及子集
  • 什么是下一代DNS
  • 如何计算VLLM本地部署Qwen3-4B的GPU最小配置应该是多少?多人并发访问本地大模型的GPU配置应该怎么分配?
  • CustomSVG,一键生成SVG,文字秒变矢量图(WIN/MAC)
  • Vue3 + ThinkPHP8 + PHP8.x 生态与 Swoole 增强方案对比分析
  • ProfiNet转Ethernet/IP网关选型策略适配西门子S7-1500与三菱变频器的关键参数对比
  • ISO 20000体系:服务级别管理含义与解释
  • RBAC(基于角色的访问控制)模型详解:从原理到实践
  • 数据库三范式详解与应用建议
  • 汽车免拆诊断案例 | 2020款奔驰E300L车发动机故障灯偶尔异常点亮
  • 具身智能:OpenAI 的真正野心与未来展望
  • PyQt学习系列06-网络编程与通信协议
  • 1537. 【中山市第十一届信息学邀请赛决赛】未命名 (noname)
  • 74. 搜索二维矩阵
  • 论文Review 地面分割 GroundGrid
  • 方案精读:92页银行数据管控体系设计方案【附全文阅读】
  • Nginx中root与alias的区别及用法
  • TCP 三次握手,第一次握手报文丢失会发生什么?