Bean 生命周期的关键阶段和详细流程

news/2025/10/21 10:46:39/文章来源:https://www.cnblogs.com/liftsail/p/19154462

1. 实例化前(Bean 定义加载与解析)

BeanDefinition 扫描与注册:Spring Boot 启动时,通过 @ComponentScan 扫描指定包(默认是主类所在包及其子包)下的类(如 @Component、@Service、@Controller 等注解标记的类),将其解析为 BeanDefinition(Bean 的元数据,包含类名、作用域、依赖等信息),注册到 BeanDefinitionRegistry 中。此外,Spring Boot 的自动配置类(@Configuration + @Conditional 等)也会通过 @EnableAutoConfiguration 机制生成 BeanDefinition 并注册。

BeanFactory 准备:Spring 容器(如 ApplicationContext)内部通过 BeanFactory(默认 DefaultListableBeanFactory)管理 BeanDefinition,此时尚未创建实际的 Bean 实例。

2. 实例化(创建 Bean 对象)

通过构造器 / 工厂方法创建实例:

容器根据 BeanDefinition 信息,调用类的构造器(默认无参构造器,若有依赖则先解析构造器参数)或指定的工厂方法(如 @Bean 方法),创建 Bean 的原始实例(内存中分配对象,属性未初始化)。

若存在多个构造器,Spring 会根据参数匹配(如 @Autowired 标记的构造器)选择合适的构造器。

3. 属性注入(依赖注入,DI)

填充属性:

容器根据 BeanDefinition 中的依赖信息,将其他 Bean 或值(如 @Value 注入的配置)通过 setter 方法、字段注入(@Autowired 直接标记字段)或 构造器注入(已在实例化阶段完成)注入到当前 Bean 中。

依赖注入的核心是通过 BeanFactory 的 getBean() 方法获取依赖的 Bean,若依赖未创建则触发其生命周期(递归过程)。

4. 初始化前(Aware 接口回调)

感知容器信息:

若 Bean 实现了 Spring 的 Aware 系列接口,容器会在初始化前回调对应的方法,注入容器相关的资源:

  • BeanNameAware:注入当前 Bean 的名称(setBeanName(String name))。

  • BeanClassLoaderAware:注入类加载器(setBeanClassLoader(ClassLoader classLoader))。

  • BeanFactoryAware:注入 BeanFactory 实例(setBeanFactory(BeanFactory beanFactory))。

  • 若容器是 ApplicationContext,还会处理 ApplicationContextAware(注入上下文)、EnvironmentAware(注入环境配置)等。

5. 初始化前(BeanPostProcessor 前置处理)

执行 BeanPostProcessor.postProcessBeforeInitialization():

所有注册到容器的 BeanPostProcessor(Bean 后置处理器)会对当前 Bean 进行前置处理。

例如:

  • AutowiredAnnotationBeanPostProcessor:处理 @Autowired、@Value 注入(补充属性注入阶段的逻辑)。

  • CommonAnnotationBeanPostProcessor:处理 @Resource、@PostConstruct 等注解。

  • 自定义 BeanPostProcessor 可在此阶段修改 Bean 实例(如代理增强)。

6. 初始化(自定义初始化逻辑)

  • 执行 @PostConstruct 注解方法:若 Bean 的方法标注了 @PostConstruct(JSR-250 规范),容器会在此阶段调用该方法(由 CommonAnnotationBeanPostProcessor 触发),用于执行初始化逻辑(如资源加载)。

  • 执行 InitializingBean 接口方法:若 Bean 实现了 InitializingBean 接口,容器会调用其 afterPropertiesSet() 方法,在属性注入完成后执行初始化逻辑。

  • 执行自定义初始化方法:若在 @Bean(initMethod = "init") 或 XML 配置中指定了初始化方法(如 <bean init-method="init"/>),容器会调用该方法。

7. 初始化后(BeanPostProcessor 后置处理)

  • 执行 BeanPostProcessor.postProcessAfterInitialization():

  • 所有 BeanPostProcessor 对当前 Bean 进行后置处理,这是 Bean 初始化完成后的最后一步修改机会。典型应用:

  • AOP 代理生成:AnnotationAwareAspectJAutoProxyCreator 在此阶段为符合条件的 Bean 创建代理对象(如被 @Transactional、@Aspect 标记的类)。

  • 自定义增强:对 Bean 进行包装或功能扩展。

8. 就绪(Bean 可用)

经过上述阶段后,Bean 已完全初始化,被放入容器的缓存中(单例 Bean 存储在 singletonObjects 缓存),可被其他 Bean 引用或通过 ApplicationContext.getBean() 获取使用。

9. 销毁前(容器关闭阶段)

  • 执行 @PreDestroy 注解方法:若 Bean 的方法标注了 @PreDestroy(JSR-250 规范),容器关闭时会调用该方法(由 CommonAnnotationBeanPostProcessor 触发),用于释放资源(如关闭连接)。

  • 执行 DisposableBean 接口方法:若 Bean 实现了 DisposableBean 接口,容器会调用其 destroy() 方法,执行销毁逻辑。

  • 执行自定义销毁方法:若在 @Bean(destroyMethod = "destroy") 或 XML 配置中指定了销毁方法(如 <bean destroy-method="destroy"/>),容器会调用该方法。

10. 销毁(Bean 回收)

容器关闭后(如 Spring Boot 应用停止),Bean 被从容器中移除,内存由 JVM 垃圾回收机制回收。

 

总结:核心流程简化

 

BeanDefinition 注册 → 实例化 → 属性注入 → Aware 回调 → 初始化前(BeanPostProcessor) → 初始化(@PostConstruct → InitializingBean → 自定义方法) → 初始化后(BeanPostProcessor) → 就绪 → 销毁前(@PreDestroy → DisposableBean → 自定义方法) → 销毁

 

Spring Boot 对该流程的简化主要体现在自动配置(减少手动注册 BeanDefinition)和默认启用常用 BeanPostProcessor(如处理注解的处理器),但核心生命周期与 Spring 框架一致。

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

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

相关文章

数字媒体技术-培优讲练-知识点总结

数字媒体技术-培优讲练-知识点总结 第一单元 “数字媒体概述” 核心内容知识模块 关键要点 具体说明 / 示例媒体三重含义 传播媒介物理媒介逻辑载体 传播媒介(电视 / 网络)物理媒介(手机 / 硬盘)逻辑载体(软件数据…

Jmeter解决响应乱码的问题

背景: 在请求里,加编码utf-8,也还是会乱码处理方案: 添加一个BeanShell后置处理器,写入以下内容,强制设置编码为utf-8 prev.setDataEncoding("UTF-8");

https://juejin.cn/post/7529730683963588627

https://juejin.cn/post/7529730683963588627https://juejin.cn/post/7529730683963588627本博客是博主个人学习时的一些记录,不保证是为原创,个别文章加入了转载的源地址,还有个别文章是汇总网上多份资料所成,在这…

实用指南:计算机毕业设计Python农作物产量预测分析 农作物爬虫 农产品可视化 农产品推荐系统 机器学习 深度学习 大数据毕业设计(源码+LW文档+PPT+详细讲解)

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

PCB布线一定不能走直角吗?一个或许有些离经叛道又颠覆常识的答案

今天收到了朋友送我的一本书(真的万分感谢,在国外买本书太不容易了,更何况朋友是直接从国内买了送给我),B站UP主JT编写的《高速PCB设计经验规则应用实践》,便趁热打铁上手看了起来。在第一章,1.5.3小节,了解经…

邮件大附件怎么发送的有效方案与技巧分享

在企业沟通中,邮件大附件的发送逐渐成为一种需求,而解决这些问题的基础在于对实际困难的理解。首先,大多数邮件系统对附件大小有严格限制,通常无法发送超过50MB的文件,这对于需要传输大型文档的用户来说是个主要障…

告别客服焦虑!用PandaWiki打造724小时AI在线客服

告别客服焦虑!用PandaWiki打造724小时AI在线客服各位正在被客服工作折磨的朋友们,是不是每天都在重复回答同样的问题?"你们几点发货?""怎么申请退款?""这个功能怎么用?"……这些问…

替代ftp的文件传输协议:提升数据安全与传输效率的新选择

在企业数字化转型过程中,找到合适的文件传输协议非常关键。替代FTP的文件传输协议不仅能有效解决传统FTP在安全性和效率上的局限,还能帮助企业降低潜在的风险。这类新协议通常集成了先进的加密技术,保障数据在传输中…

Jmeter解决临界部分控制器,锁限流的问题

背景: 发现加了临界部分控制器,TPS上不去,发现是锁限流了处理方案: 修改锁,改成动态的: global_lock_${__threadNum}

Gitee DevOps:中国企业的研发效能加速器

Gitee DevOps:中国企业的研发效能加速器 在数字化转型的加速跑道上,中国企业正面临前所未有的研发效能挑战。随着《网络安全法》《数据安全法》等法规的落地实施,以及混合办公模式成为新常态,传统的软件开发模式正…

软件中版本号V1.0.0含义

软件中版本号V1.0.0含义主版本号:当进行了不兼容的API修改或重大更新时,递增主版本号 次版本号:当增加了向后兼容的新功能时,递增次版本号 修订版本号:当进行了向后兼容的问题修复时,递增修订版本号

LabVIEW继电保护检测 - 教程

LabVIEW继电保护检测 - 教程pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco",…

软件测试-缺陷管理篇

一.软件缺陷有四种级别,分别为:致命的(Fatal),严重的(Critical),一般的(Major),微小的(Minor)。 A类—致命的软件缺陷(Fatal): 造成系统或应用程序崩溃、死机、系统挂起,或造成数据丢失,主要功能完全丧失,导致…

数据安全交换系统介绍及其应用场景分析

数据安全交换系统是一种通过技术手段确保信息在不同网络之间安全传输的解决方案。它的关键作用在于保护数据的机密性和完整性,防止未授权访问和信息泄露。该系统运用多重加密、访问控制和实时监测等功能,从而有效应对…

vue项目引入iconfont(阿里巴巴矢量图标库)

阿里巴巴矢量图标网址:https://www.iconfont.cn/manage/index?manage_type=myprojects&projectId=3818294 一、方式1:项目中使用usicon引用图标 1.下载代码 选择图标加入项目中后,下载图标代码下载后解压2.Vue项…

DBeaver 设置语言为中文

DBeaver 设置语言为中文在dbeaver安装目录下编辑dbeaver.ini 文件,在-vmargs 上面插入 -nl 和 zh ,如下图: -nlzh 然后保存,再重启 Dbeaver 就可以了。 工具栏已经改成中文了

什么是文件摆渡系统?全面解析企业数据安全交换的核心工具

在数字化时代,企业数据跨网络流转日益频繁,但不同网络环境(如内网与外网、生产网与办公网)的隔离要求,以及数据泄露、病毒入侵等风险,让传统文件传输方式(如 U 盘、邮件、FTP)难以满足安全与合规需求。此时,文…

Gitee崛起:中国开发者生态的战略升级与未来布局

Gitee崛起:中国开发者生态的战略升级与未来布局 在中国数字经济高速发展的背景下,代码托管平台正在经历一场深刻的变革。作为国内领先的代码托管服务提供商,Gitee凭借其本土化优势和持续创新能力,正在重塑中国开发…

Docker Compose v2.35.1 更新!

Docker Compose v2.35.1 更新!绑定挂载改进,进一步提升了稳定性和安全性 • 通过 Docker Desktop 自动更新,或手动运行:docker compose version # 查看当前版本 docker compose pull # 拉取最新镜像 • 使用包管理…

国内开发者如何选择最适合的代码管理工具?Gitee、GitHub、Bitbucket横向评测

国内开发者如何选择最适合的代码管理工具?Gitee、GitHub、Bitbucket横向评测 在数字化转型浪潮下,代码管理工具已成为开发者日常工作的必备利器。面对众多选择,国内开发者该如何做出明智决策?本文将从本土化需求、…