文章目录

  • 🌱 《Spring IOC核心:Bean生命周期全解析》
    • 1️⃣ 引言:Bean 生命周期为什么重要?
    • 2️⃣ Bean 生命周期概览(图示 + 简要说明)
    • 3️⃣ 每一步详细解析(源码理解 + 示例)
      • 3.1 🧱 实例化(构造函数)
      • 3.2 🧩 属性注入(Setter、@Value、@Autowired)
      • 3.3 🔎 Aware 接口(Bean 开始“认识环境”)
      • 3.4 ⚙️ 初始化阶段(核心阶段!)
        • ✅ 方式1:实现 InitializingBean
        • ✅ 方式2:使用 @PostConstruct
        • ✅ 方式3:init-method 配置(XML 或 @Bean)
        • ✅ BeanPostProcessor:初始化前后增强
      • 3.5 🧑‍🔧 使用阶段(容器托管中)
      • 3.6 💣 销毁阶段
        • ✅ 方式1:实现 DisposableBean
        • ✅ 方式2:使用 @PreDestroy
        • ✅ 方式3:destroy-method 配置
    • 4️⃣ 实战演示:一个 Bean 完整生命周期打印示例
    • 5️⃣ 常见误区与调试技巧
    • 6️⃣ 总结 & 推荐实践
    • 📘 延伸阅读

🌱 《Spring IOC核心:Bean生命周期全解析》

目标读者:
使用 Spring 的 Java 后端开发者,
想深入理解 Bean 的创建、初始化、销毁全过程,
以写出更加健壮、可控、可调试的应用代码。


1️⃣ 引言:Bean 生命周期为什么重要?

Bean,不是你 new 出来的,而是 Spring 创建并“托管”的!

在 Spring 框架中,Bean 是最核心的组件之一,但我们很多时候对它的 “出生 → 成长 → 退休” 过程了解得并不完整。

类比一下:
Spring 就像一个“高级托儿所”,Bean 是被托管的小朋友,从出生到离园都有严格的流程规范。

理解这个生命周期,不仅能帮助我们进行框架扩展、调试 Bug,更是理解 Spring “魔法”的第一步!


2️⃣ Bean 生命周期概览(图示 + 简要说明)

         ┌────────────┐│ 实例化 Instantiation└────┬───────┘↓┌────────┴────────┐│ 属性填充 Populate│└────────┬────────┘↓┌────────────┴────────────┐│ Aware 回调(BeanNameAware等)└────────────┬────────────┘↓┌────────────┴────────────┐│ 初始化:@PostConstruct / init-method│ + BeanPostProcessor 执行└────────────┬────────────┘↓┌────────┴────────┐│  Bean 被使用中  │└────────┬────────┘↓┌────────────┴────────────┐│ 销毁:@PreDestroy / destroy-method└─────────────────────────┘

3️⃣ 每一步详细解析(源码理解 + 示例)

3.1 🧱 实例化(构造函数)

Spring 首先通过 构造函数反射 实例化 Bean。

public class MyBean {public MyBean() {System.out.println("1️⃣ 实例化阶段");}
}

3.2 🧩 属性注入(Setter、@Value、@Autowired)

Spring 在实例化后,为 Bean 注入属性。

@Component
public class MyBean {@Value("${my.value:default}")private String value;@Autowiredprivate Dependency dependency;public void setValue(String value) {System.out.println("2️⃣ 属性注入:" + value);this.value = value;}@Autowiredpublic void setDependency(Dependency dependency) {System.out.println("2️⃣ 属性注入:依赖注入完成");this.dependency = dependency;}
}

3.3 🔎 Aware 接口(Bean 开始“认识环境”)

Bean 想知道自己叫什么、谁在托管我、我在哪个容器中?就实现这些接口。

@Component
public class MyBean implements BeanNameAware, BeanFactoryAware, ApplicationContextAware {public void setBeanName(String name) {System.out.println("3️⃣ BeanNameAware:我的名字是 " + name);}public void setBeanFactory(BeanFactory factory) {System.out.println("3️⃣ BeanFactoryAware:我被 BeanFactory 托管");}public void setApplicationContext(ApplicationContext ctx) {System.out.println("3️⃣ ApplicationContextAware:我已感知到容器");}
}

3.4 ⚙️ 初始化阶段(核心阶段!)

Spring 让你“准备就绪”,可以做初始化逻辑了。

✅ 方式1:实现 InitializingBean
@Override
public void afterPropertiesSet() throws Exception {System.out.println("4️⃣ InitializingBean:属性注入后初始化");
}
✅ 方式2:使用 @PostConstruct
@PostConstruct
public void init() {System.out.println("4️⃣ @PostConstruct:初始化方法执行");
}
✅ 方式3:init-method 配置(XML 或 @Bean)
@Bean(initMethod = "init")
public MyBean myBean() {return new MyBean();
}
✅ BeanPostProcessor:初始化前后增强
@Component
public class MyBeanPostProcessor implements BeanPostProcessor {public Object postProcessBeforeInitialization(Object bean, String name) {System.out.println("⚙️ Before Init: " + name);return bean;}public Object postProcessAfterInitialization(Object bean, String name) {System.out.println("⚙️ After Init: " + name);return bean;}
}

3.5 🧑‍🔧 使用阶段(容器托管中)

此阶段 Bean 被容器管理、可被其他组件注入、调用。

@Component
public class UserService {@Autowiredprivate MyBean myBean;public void use() {System.out.println("5️⃣ Bean 正在被使用中");}
}

3.6 💣 销毁阶段

Spring 容器关闭时,执行销毁逻辑。

✅ 方式1:实现 DisposableBean
@Override
public void destroy() throws Exception {System.out.println("6️⃣ DisposableBean:销毁中");
}
✅ 方式2:使用 @PreDestroy
@PreDestroy
public void destroyMethod() {System.out.println("6️⃣ @PreDestroy:销毁逻辑");
}
✅ 方式3:destroy-method 配置
@Bean(destroyMethod = "cleanup")
public MyBean myBean() {return new MyBean();
}

⚠️ 注意:@Scope(“prototype”) 的 Bean 容器不负责销毁!需手动释放资源。

4️⃣ 实战演示:一个 Bean 完整生命周期打印示例

@Component
public class LifeCycleBean implements BeanNameAware, InitializingBean, DisposableBean {public LifeCycleBean() {System.out.println("1️⃣ 构造方法执行:实例化");}@Autowiredpublic void setDependency(Dependency dep) {System.out.println("2️⃣ 属性注入");}@Overridepublic void setBeanName(String name) {System.out.println("3️⃣ 感知容器:我的名字是 " + name);}@PostConstructpublic void postConstruct() {System.out.println("4️⃣ 初始化:@PostConstruct");}@Overridepublic void afterPropertiesSet() {System.out.println("4️⃣ 初始化:afterPropertiesSet");}@PreDestroypublic void preDestroy() {System.out.println("6️⃣ 销毁:@PreDestroy");}@Overridepublic void destroy() {System.out.println("6️⃣ 销毁:destroy()");}
}

控制台输出:

1️⃣ 构造方法执行:实例化
2️⃣ 属性注入
3️⃣ 感知容器:我的名字是 lifeCycleBean
4️⃣ 初始化:@PostConstruct
4️⃣ 初始化:afterPropertiesSet
⚙️ Bean 使用中...
6️⃣ 销毁:@PreDestroy
6️⃣ 销毁:destroy()

5️⃣ 常见误区与调试技巧

问题描述可能原因
@PostConstruct 不执行Bean 没被容器管理,或被 @Configuration 注册成了 Lite 模式
BeanPostProcessor 顺序异常实现了多个 BPP 接口但未排序,可实现 Ordered 解决
原型 Bean 不执行 destroy@Scope("prototype") 的 Bean 不受容器销毁管理
生命周期日志没打印@Component 没扫到;或被懒加载;或依赖未注入

6️⃣ 总结 & 推荐实践

  • Bean 生命周期是 Spring 提供扩展能力的核心入口;
  • 推荐使用 @PostConstruct 和 @PreDestroy 进行初始化/销毁管理;
  • 多个初始化方式优先级为:@PostConstruct > InitializingBean > init-method;
  • 掌握 Bean 生命周期 = 掌握 Spring 魔法的第一步!

📘 延伸阅读

  • Spring 源码 AbstractBeanFactory
  • 《Spring 实战》第 4 章 Bean 生命周期
  • 官方文档:Bean Lifecycle

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/pingmian/88492.shtml
繁体地址,请注明出处:http://hk.pswp.cn/pingmian/88492.shtml
英文地址,请注明出处:http://en.pswp.cn/pingmian/88492.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Python 类型注解实战:`Optional` 与安全数据处理的艺术

Python 类型注解实战:Optional 与安全数据处理的艺术 在 Python 开发中,类型注解(Type Hints)已经成为现代 Python 项目的标配。本文将通过一个真实的认证令牌获取函数 get_auth_token(),深入解析 Optional 类型的应用…

深入MyBatis:CRUD操作与高级查询实战

引言 在上一篇文章中,我们介绍了Mybatis的基础使用。 如有需要请移步查看: MyBatis入门:快速掌握用户查询实战https://blog.csdn.net/qq_52331401/article/details/149270402?spm1001.2014.3001.5502 今天,我将通过一个完整的…

Flink DataStream API详解(二)

一、引言 咱两书接上回,上一篇文章主要介绍了DataStream API一些基本的使用,主要是针对单数据流的场景下,但是在实际的流处理场景中,常常需要对多个数据流进行合并、拆分等操作,以满足复杂的业务需求。Flink 的 DataS…

Unity3D游戏线上崩溃排查指南

前言 排查Unity3D线上游戏崩溃是个系统工程,需要结合工具链、日志分析和版本管理。以下是详细的排查指南和关键步骤: 对惹,这里有一个游戏开发交流小组,希望大家可以点击进来一起交流一下开发经验呀! 一、崩溃信息收…

DPDK性能优化实践:系统级性能调优的方法论与实战(一套通用的方法论)

性能优化的挑战与现实困境 在高性能网络处理领域,性能优化往往被视为一门“玄学”而非科学。许多开发者在面对性能瓶颈时,要么盲目追求单一指标的极致优化,要么采用"试错法"进行零散的局部调优,结果往往是投入大量精力却…

Docker的/var/lib/docker/目录占用100%的处理方法

文章目录 一、问题描述 二、解决措施 三、可能遇到的问题 问题1、问题描述:执行 sudo systemctl stop docker 命令时,提示 Warning: Stopping docker.service, but it can still be activated by: docker.socket 问题2、问题描述:执行 s…

【UE教程/进阶】Slate链式编辑原理

目录链式编辑操作" . "操作" "操作" [ ] "链式编辑 SNew().[] 操作" . " SLATE_ARGUMENT(ArgType, ArgName) 宏 调用宏 SLATE_PRIVATE_ARGUMENT_VARIABLE(ArgType, ArgName) ,在FArgument结构体中添加了变量…

将手工建模模型(fbx、obj)转换为3dtiles的免费工具!

文章目录1、工具下载2、使用说明3、详细说明命令行格式示例命令参数说明4、源码地址1、工具下载 百度网盘下载链接 选择最新版本下载即可,支持Linux和Windows系统 2、使用说明 1)按住键盘winr键,在弹出的窗口中输入cmd 2)点击…

FreeRTOS源码学习之内核初始化

目录 前言 一、主函数内容 二、osKernelInitialize ()内核初始化函数内容 三、IS_IRQ()宏定义中断检测函数内容 四、如果这篇文章能帮助到你,请点个赞鼓励一下吧ξ( ✿>◡❛)~ 前言 使用STM32CubeMX添加FreeRTOS进入工程之后,会自动在ma…

Docker—— 镜像构建原因

在现代软件开发和运维中,Docker已成为一种非常流行的工具,它通过容器化应用程序来简化部署过程。然而,默认的官方镜像往往只能满足基础需求,无法涵盖所有特定项目的具体要求。原因说明系统级改动无法通过 volume 实现修改用户、删…

锂电池自动化生产线的现状与发展

锂电池自动化生产线的概述锂电池自动化生产线是指采用自动化设备和控制系统,实现锂电池从原材料到成品的全流程自动化生产过程。随着新能源产业的快速发展,锂电池作为重要的储能元件,其生产制造技术也在不断进步。自动化生产线通过减少人工干…

java底层的native和沙箱安全机制

沙箱安全机制沙箱(Sandbox)安全机制是一种将程序或代码运行在隔离环境中的安全技术,旨在限制其对系统资源(如文件系统、网络、内存、其他进程等)的访问权限,从而降低潜在恶意代码带来的风险。其核心思想是“…

【分享】文件摆渡系统适配医疗场景:安全与效率兼得

根据国家信息安全相关法规要求,医院为了网络安全,大多会采用网闸等隔离手段,将网络隔离为内网和外网,但网络隔离后,医院的内外网间仍存在较为频繁的文件摆渡需求。文件摆渡系统则是可以解决跨网络或跨安全域文件传输中…

vscode 中的 mermaid

一、安装软件 Mermaid preview Mermaid support 二、运行命令 创建.md 文件右键选择 ​Open Preview​(或按 CtrlShiftV) 三、流程图 注意: 要md 文件要保留 mermaid 1. #mermaid-svg-nchqbvlWePe5KCwJ {font-family:"trebuchet ms"…

微服务引擎 MSE 及云原生 API 网关 2025 年 6 月产品动态

点击此处,了解微服务引擎 MSE 产品详情。

【TCP/IP】7. IP 路由

7. IP 路由7. IP 路由概述7.1 直接传递与间接传递7.2 IP 路由核心机制7.3 路由表7.3.1 路由表的构成7.3.2 信宿地址采用网络地址的好处7.3.3 下一跳地址的优势7.3.4 特殊路由表项7.3.5 路由算法7.4 静态路由7.4.1 特点7.4.2 自治系统(AS)7.4.3 配置命令7…

xFile:高性能虚拟分布式加密存储系统——Go

xFile:高性能虚拟分布式加密存储系统 目录xFile:高性能虚拟分布式加密存储系统1 背景介绍2 设计初衷与目标3 项目简介4 系统架构5 核心优势1. 真正的分布式块存储2. 块级加密与压缩,安全高效3. 灵活的索引与元数据管理4. 多用户与权限体系5. …

时序数据库:高效处理时间序列数据的核心技术

时序数据库概述时序数据库(Time Series Database,TSDB)是一种专门为存储、处理和查询时间序列数据而优化的数据库系统。随着物联网、金融科技、工业互联网等领域的快速发展,时序数据呈现出爆炸式增长,传统的关系型数据…

面试官:你再问TCP三次握手,我就要报警了!

CP三次握手和四次挥手,是面试官最爱问的“开场白”之一 别看它基础,真要讲清楚细节,分分钟让你冷汗直流! 这玩意儿就跟程序员相亲一样: 表面上问的是“你老家哪的” 实际上是在试探你有没有房、有没有车、能不能落…

RuoYi+Uniapp(uni-ui)开发商城系统

如果你正在考虑用 RuoYi 和 UniApp(uni-ui)搭建一套商城系统,那这套组合确实值得好好研究。它整合了 RuoYi 的快速开发能力和 UniApp 的跨平台特性,在高效开发的同时还能兼顾多端适配的需求。下面从技术架构、功能模块、开发实践到…