【Java 开发日记】我们来说一下 bean 的生命周期

【Java 开发日记】我们来说一下 bean 的生命周期

目录

Bean 生命周期的详细步骤

第一阶段:Bean 的元数据配置与容器启动

第二阶段:Bean 的实例化与初始化(核心生命周期)

第三阶段:Bean 的使用与销毁

特殊情况的处理

总结与记忆技巧


为了更直观地理解,我们可以将整个生命周期分为几个大的阶段,下图清晰地展示了这一过程:

Bean 生命周期的详细步骤

第一阶段:Bean 的元数据配置与容器启动
  1. 配置元数据:首先,你需要通过 XML、Java 注解(如 @Component@Service@Autowired)或 Java 配置类(@Configuration@Bean)来定义 Bean。
  2. 容器启动:Spring 容器(如 ApplicationContext)启动,加载并解析这些配置元数据,生成每个 Bean 的 BeanDefinition 对象,它包含了创建一个 Bean 所需的所有信息(如类名、作用域、是否懒加载等)。
第二阶段:Bean 的实例化与初始化(核心生命周期)

1. 实例化(Instantiation)

  • 描述:容器首先会调用 Bean 的构造函数(或工厂方法)来创建一个新的实例。此时只是一个简单的 Java 对象,还没有进行依赖注入,我们可以把它比作“新生儿”。
  • 扩展点:无直接扩展点。

2. 依赖注入(Populate Properties)

  • 描述:Spring 根据配置(如 @Autowired@Value)将所需的依赖注入到 Bean 的对应属性中。这一步填充了 Bean 的“血肉”。
  • 扩展点:无直接扩展点。

3. Aware 接口回调(Aware Interface Injection)

  • 描述:如果 Bean 实现了各种 Aware 接口,Spring 会在此阶段回调相应的方法,将一些容器相关的对象(如 BeanNameAwareBeanFactoryAwareApplicationContextAware)注入到 Bean 中。
  • 扩展点
    • BeanNameAware:设置 Bean 的 ID/Name。
    • BeanFactoryAware:设置当前的 BeanFactory
    • ApplicationContextAware:设置当前的 ApplicationContext(功能最全)。
    • EnvironmentAware:设置 Environment 对象(用于获取配置文件属性)等。

4. BeanPostProcessor 前置处理

  • 描述:这是极其重要的扩展点。所有实现了 BeanPostProcessor 接口的 Bean,它们的 postProcessBeforeInitialization 方法会在这个阶段被调用。它可以对 Bean 进行包装或增强,返回一个可能是代理对象的 Bean。
  • 扩展点BeanPostProcessor.postProcessBeforeInitialization(Object bean, String beanName)

5. 初始化(Initialization)

  • 描述:Bean 的“成人礼”。在这个阶段,Bean 的初始化逻辑会被执行。
    • a. InitializingBean 接口:如果 Bean 实现了 InitializingBean 接口,会调用其 afterPropertiesSet() 方法。
    • b. 自定义初始化方法:调用通过 @Bean(initMethod = "...") 或 XML 中 init-method 属性指定的自定义初始化方法。
  • 扩展点
    • InitializingBean.afterPropertiesSet()
    • 自定义 init-method

6. BeanPostProcessor 后置处理

  • 描述:这是另一个极其重要的扩展点。所有 BeanPostProcessor 的 postProcessAfterInitialization 方法会被调用。Spring AOP 就是基于此实现的。如果一个 Bean 需要被代理,通常在这里返回一个代理对象来包装目标 Bean。
  • 扩展点BeanPostProcessor.postProcessAfterInitialization(Object bean, String beanName)

7. Bean 就绪(Ready)

  • 描述:经过以上所有步骤,Bean 已经完全创建、初始化并可能被代理。它被存放在 Spring 容器(单例池)中,可以被应用程序正常获取和使用了。
第三阶段:Bean 的使用与销毁

8. 使用期

  • 描述:在应用程序运行期间,Bean 被其他组件依赖和调用,执行业务逻辑。

9. 销毁(Destruction)

  • 描述:当 Spring 容器(通常是 ApplicationContext)被关闭时,它会开始销毁容器中的所有单例 Bean。
    • a. DisposableBean 接口:如果 Bean 实现了 DisposableBean 接口,会调用其 destroy() 方法。
    • b. 自定义销毁方法:调用通过 @Bean(destroyMethod = "...") 或 XML 中 destroy-method 属性指定的自定义销毁方法。常用于释放资源,如关闭数据库连接、文件句柄等。
  • 扩展点
    • DisposableBean.destroy()
    • 自定义 destroy-method

特殊情况的处理

  • 作用域(Scope):上述生命周期主要针对单例(Singleton) Bean。对于原型(Prototype) 作用域的 Bean,Spring 容器只负责到第 6 步(初始化完成),之后就将 Bean 交给客户端,不再管理其生命周期,因此不会调用销毁方法。
  • 延迟初始化(Lazy):标记为 @Lazy 的 Bean,只有在第一次被请求时才会触发上述初始化过程,而不是在容器启动时。

总结与记忆技巧

可以把这个过程想象成一个人的一生:

  • 实例化:出生
  • 依赖注入:接受教育,获取生存技能(依赖)
  • Aware 接口:获得身份ID、认识家庭和社会(容器环境)
  • BeanPostProcessor(前):步入社会前的指导
  • 初始化:举行成人礼,开始独立承担责任
  • BeanPostProcessor(后):步入社会后的包装/历练(可能被“代理”)
  • 就绪:成为社会栋梁,贡献力量
  • 销毁:退休,安享晚年,处理身后事

如果小假的内容对你有帮助,请点赞评论收藏。创作不易,大家的支持就是我坚持下去的动力!

Read more

如何快速实现无人机RemoteID合规?ArduRemoteID开源方案完整指南

如何快速实现无人机RemoteID合规?ArduRemoteID开源方案完整指南 【免费下载链接】ArduRemoteIDRemoteID support using OpenDroneID 项目地址: https://gitcode.com/gh_mirrors/ar/ArduRemoteID ArduRemoteID是一个专为无人机设计的开源RemoteID解决方案,基于OpenDroneID标准实现,完美支持FAA与欧盟法规要求。通过MAVLink和DroneCAN协议与飞行控制器通信,提供WiFi广播、蓝牙5等多种传输模式,兼容ESP32-S3/C3等主流硬件平台,帮助开发者轻松实现无人机身份识别功能。 🚁 项目核心功能解析 多协议兼容的身份发射系统 ArduRemoteID模块集成了MAVLink与DroneCAN双协议支持,可无缝对接ArduPilot等主流飞控系统。通过RemoteIDModule/transmitter.cpp实现的发射逻辑,能同时广播无人机位置、速度、高度等关键飞行数据,确保监管平台实时获取设备状态。 全平台硬件适配方案 支持ESP3

By Ne0inhk
腾讯QQ官方炸场!OpenClaw一键建5个机器人,个人号直接上手|实战教程

腾讯QQ官方炸场!OpenClaw一键建5个机器人,个人号直接上手|实战教程

文章目录 * 前言 * 一、OpenClaw是个啥?你的"数字长工" * 二、为什么说这次QQ"炸场"了? * 三、实操环节:从0到1,手把手养出你的AI小弟 * 3.1 在QQ开放平台"造人" * 3.2 给机器人找个"肉身"(部署OpenClaw) * 方案A:云服务器一键部署(推荐新手) * 方案B:宝塔面板可视化安装(适合有服务器的站长) * 方案C:本地Docker部署(适合极客) * 3.3 关键的"认亲"三步走 * 3.4 加好友,

By Ne0inhk
轮腿机器人代码调试补充

轮腿机器人代码调试补充

* @Author: 星夜雨夜 * @brief: 轮腿基础代码编写调试补充,移植自达妙开源代码 * @attention:笔者默认读者已经熟练掌握机甲大师RoboMaster c型开发板例程代码的底盘代码和INS_task.c陀螺仪代码、熟练掌握各电机can协议和遥控器dbus协议。默认读者已能看懂轮腿圣经和玺佬的五连杆运动学解算与VMC。建议读者仔细研读轮腿圣经3~5遍,边看MATLAB文件和达妙开源代码,掌握轮腿调试和编写大致思路。一定要注意各状态变量的单位和正负号是否正确,轮腿调试过程中,最难之处在于极性是否正确。本车所有电机均为逆时针旋转为正方向。 !!!强烈建议读者在开发轮腿之前,先运用LQR算法完成一阶倒立摆的平衡小车(即板凳模型)的实现 !!!如果时间紧,其实完全可以不搞仿真,直接实机开调。仿真不疯,实物不一定不疯;但实物疯,仿真必疯。 调试成果展示视频链接(抖音):轮腿机器人 一阶倒立摆平衡小车参考资料: 1.本科毕设 轮腿式双足机器人 开源文件演示_哔哩哔哩_bilibili(资料在视频评论区) 2.达妙平衡小车开源:[达妙科技开源系列-平衡小车] 第一弹_哔哩

By Ne0inhk

基于Verilog的数字密码锁设计与FPGA实现

1. 项目概述:从零打造一个FPGA数字密码锁 大家好,今天我想和大家分享一个特别实用的FPGA项目——用Verilog设计一个数字密码锁。这个项目不仅适合初学者入门,也包含了一些进阶功能,能够让你全面掌握数字电路设计的精髓。我自己在第一次做这个项目时踩过不少坑,但也收获了很多实战经验,现在把这些经验毫无保留地分享给大家。 数字密码锁是我们日常生活中常见的设备,但你可能从来没想过自己也能用FPGA来实现一个。这个项目最大的魅力在于,你不仅能学到Verilog编程技巧,还能亲手把代码烧录到FPGA开发板上,看到实实在在的硬件运行效果。我选择的密码锁设计支持4位数字密码,每位密码范围是0-5,而且还加入了密码修改、错误次数限制等实用功能。 如果你刚开始接触FPGA,可能会觉得硬件描述语言有点抽象。别担心,我会用最直白的方式解释每个设计环节。实际做下来,从编写代码到功能验证,完整流程大概需要2-3天时间。最重要的是,这个项目能让你真正理解状态机设计的思想,这是数字电路设计的核心概念之一。 2. 设计思路与架构规划 2.1 核心功能定义 在设计之初,我仔细规划了密码锁需要实现的功

By Ne0inhk