Spring Bean生命周期七步曲:定义、实例化、初始化、使用、销毁

各位小猿,程序员小猿开发笔记,希望大家共同进步。

引言

1.整体流程图

在这里插入图片描述

2.各阶段分析

1️⃣定义阶段

1.1 定位资源

  • Spring 扫描 @Component@Service@Controller 等注解的类
  • 或解析 XML/Java Config 中的 Bean 定义

1.2定义 BeanDefinition

  • 解析类信息(作用域、懒加载、初始化/销毁方法等)
  • 将解析结果封装为 BeanDefinition 对象
  • 存储到 BeanDefinitionRegistry (通常是 DefaultListableBeanFactory)

1.3发布到容器

  • BeanDefinition 注册完成,但尚未实例化
  • 此时可通过 BeanFactory 获取 Bean 的定义信息

发布,已经定义的bean到IOC容器中

1.4实例化bean

  • 容器通过反射调用构造函数创建原始对象
  • 若存在构造器依赖,优先解决循环依赖(三级缓存机制)

1.5完成相关依赖注入

  • 处理 @Autowired@Value@Resource 等注解
  • 填充普通属性和集合类型

2️⃣初始化

2.1setName方法

  • BeanNameAware.setBeanName()

2.2setBeanFactory

  • BeanFactoryAware.setBeanFactory()

2.3setApplicationContext

  • ApplicationContextAware.setApplicationContext()

2.4postProcessorBeforeInitislization()前置处理方法

  • BeanPostProcessor.postProcessBeforeInitialization()
  • 典型应用:@PostConstruct 注解处理、代理生成(如 AOP)

2.5调用 InitializingBean.afterPropertiesSet()

2.6执行自定义 init-method(XML 或 @Bean(initMethod)

2.6BeanPostProcessor 后置处理

  • BeanPostProcessor.postProcessAfterInitialization()
  • 典型应用:AOP 最终代理、监控增强

2.7postProcessorAfterInitislization()后置处理方法

3️⃣准备使用

  • Bean 正式服务于应用程序
  • 所有依赖和方法均可正常使用

4️⃣自定义销毁方法

  1. 销毁前置处理
    • DestructionAwareBeanPostProcessor.postProcessBeforeDestruction()
  2. 销毁方法执行(按顺序)
    • 调用 @PreDestroy 注解方法
    • 执行 DisposableBean.destroy()
    • 执行自定义 destroy-method(XML 或 @Bean(destroyMethod)
  3. 资源释放
    • 断开数据库连接
    • 停止线程池
    • 释放文件句柄等资源

3.注意事项

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.*;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;// 1. 定义 Bean 类(演示所有生命周期接口)
class ProductService implements BeanNameAware, BeanFactoryAware, ApplicationContextAware,InitializingBean, DisposableBean {private String productName;// 1.1 构造器(实例化阶段)public ProductService() {System.out.println("🚀 1. 实例化阶段: 调用构造器创建 ProductService 实例");}// 1.2 属性注入(依赖注入阶段)public void setProductName(String productName) {this.productName = productName;System.out.println("🔄 2. 依赖注入: setProductName() 注入属性值: " + productName);}// 2.1 BeanNameAware 回调@Overridepublic void setBeanName(String name) {System.out.println("🔖 3.1 Aware 接口: setBeanName() → Bean ID: " + name);}// 2.2 BeanFactoryAware 回调@Overridepublic void setBeanFactory(BeanFactory beanFactory) throws BeansException {System.out.println("🏭 3.2 Aware 接口: setBeanFactory() → BeanFactory 已注入");}// 2.3 ApplicationContextAware 回调@Overridepublic void setApplicationContext(ApplicationContext applicationContext) throws BeansException {System.out.println("🌐 3.3 Aware 接口: setApplicationContext() → ApplicationContext 已注入");}// 2.4 自定义初始化方法 (通过 @Bean 指定)public void customInit() {System.out.println("🔧 5.1 初始化: 执行 @Bean 指定的 customInit()");}// 2.5 @PostConstruct 方法@PostConstructpublic void postConstructInit() {System.out.println("🔧 4.1 初始化: 执行 @PostConstruct 方法");}// 2.6 InitializingBean 接口@Overridepublic void afterPropertiesSet() {System.out.println("🔧 5.2 初始化: 执行 InitializingBean.afterPropertiesSet()");}// 3. 业务方法public void displayProduct() {System.out.println("🛒 6. 使用阶段: 当前产品 → " + productName);}// 4.1 @PreDestroy 方法@PreDestroypublic void preDestroy() {System.out.println("♻️ 7.1 销毁阶段: 执行 @PreDestroy 方法");}// 4.2 DisposableBean 接口@Overridepublic void destroy() {System.out.println("♻️ 7.2 销毁阶段: 执行 DisposableBean.destroy()");}// 4.3 自定义销毁方法 (通过 @Bean 指定)public void customDestroy() {System.out.println("♻️ 7.3 销毁阶段: 执行 @Bean 指定的 customDestroy()");}
}// 2. 自定义 BeanPostProcessor(演示扩展点)
class CustomBeanPostProcessor implements BeanPostProcessor {@Overridepublic Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {if (bean instanceof ProductService) {System.out.println("⚙️ 4. 初始化前: BeanPostProcessor.postProcessBeforeInitialization()");}return bean;}@Overridepublic Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {if (bean instanceof ProductService) {System.out.println("⚙️ 5.3 初始化后: BeanPostProcessor.postProcessAfterInitialization()");}return bean;}
}// 3. Spring 配置类
@Configuration
class AppConfig {@Bean(initMethod = "customInit", destroyMethod = "customDestroy")public ProductService productService() {ProductService service = new ProductService();service.setProductName("iPhone 15"); // 属性注入return service;}@Beanpublic CustomBeanPostProcessor customBeanPostProcessor() {return new CustomBeanPostProcessor();}
}// 4. 主应用类
public class BeanLifecycleDemo {public static void main(String[] args) {System.out.println("============ 启动 Spring 容器 ============");AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);System.out.println("\n============ 使用阶段 ============");ProductService productService = context.getBean(ProductService.class);productService.displayProduct();System.out.println("\n============ 关闭 Spring 容器 ============");context.close(); // 触发销毁阶段}
}

输出结果展示

============ 启动 Spring 容器 ============
🚀 1. 实例化阶段: 调用构造器创建 ProductService 实例
🔄 2. 依赖注入: setProductName() 注入属性值: iPhone 15
🔖 3.1 Aware 接口: setBeanName() → Bean ID: productService
🏭 3.2 Aware 接口: setBeanFactory() → BeanFactory 已注入
🌐 3.3 Aware 接口: setApplicationContext() → ApplicationContext 已注入
⚙️ 4. 初始化前: BeanPostProcessor.postProcessBeforeInitialization()
🔧 4.1 初始化: 执行 @PostConstruct 方法
🔧 5.1 初始化: 执行 @Bean 指定的 customInit()
🔧 5.2 初始化: 执行 InitializingBean.afterPropertiesSet()
⚙️ 5.3 初始化后: BeanPostProcessor.postProcessAfterInitialization()============ 使用阶段 ============
🛒 6. 使用阶段: 当前产品 → iPhone 15============ 关闭 Spring 容器 ============
♻️ 7.1 销毁阶段: 执行 @PreDestroy 方法
♻️ 7.2 销毁阶段: 执行 DisposableBean.destroy()
♻️ 7.3 销毁阶段: 执行 @Bean 指定的 customDestroy()

生命周期阶段详解:

  1. 实例化阶段
    • 调用构造函数创建 Bean 实例
  2. 依赖注入
    • 通过 setter 或字段注入属性值
  3. Aware 接口回调(按顺序)
    • BeanNameAwareBeanFactoryAwareApplicationContextAware
  4. 初始化前处理
    • BeanPostProcessor.postProcessBeforeInitialization()
  5. 初始化阶段(按顺序)
    • @PostConstruct 方法 → 自定义 init-methodInitializingBean.afterPropertiesSet()
  6. 初始化后处理
    • BeanPostProcessor.postProcessAfterInitialization()(如 AOP 代理在此生成)
  7. 使用阶段
    • Bean 完全初始化,可被应用程序使用
  8. 销毁阶段(容器关闭时)
    • @PreDestroyDisposableBean.destroy() → 自定义 destroy-method

关键点说明:

  1. 执行顺序:初始化方法按 @PostConstructInitializingBeaninit-method 顺序执行
  2. 扩展点BeanPostProcessor 可干预初始化过程(如 AOP、事务代理)
  3. 销毁顺序:与初始化顺序相反(栈结构)
  4. 作用域影响:原型(prototype) Bean 不执行销毁方法ß

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

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

相关文章

API安全监测工具:数字经济的免疫哨兵

💥 企业的三重致命威胁 1. 漏洞潜伏的定时炸弹 某支付平台未检测出API的批量数据泄露漏洞,导致230万用户信息被盗,面临GDPR 1.8亿欧元罚单(IBM X-Force 2024报告)。传统扫描器对逻辑漏洞漏检率超40%(OWASP基…

Matplotlib详细教程(基础介绍,参数调整,绘图教程)

目录 一、初识Matploblib 1.1 安装 Matplotlib 1.2、Matplotlib 的两种接口风格 1.3、Figure 和 Axes 的深度理解 1.4 设置画布大小 1.5 设置网格线 1.6 设置坐标轴 1.7 设置刻度和标签 1.8 添加图例和标题 1.9 设置中文显示 1.10 调整子图布局 二、常用绘图教程 2…

Redis高可用架构演进面试笔记

1. 主从复制架构 核心概念Redis单节点并发能力有限,通过主从集群实现读写分离提升性能: Master节点:负责写操作Slave节点:负责读操作,从主节点同步数据 主从同步流程 全量同步(首次同步)建立连接…

无人机保养指南

定期清洁无人机在使用后容易积累灰尘、沙砾等杂物,需及时清洁。使用软毛刷或压缩空气清除电机、螺旋桨和机身缝隙中的杂质。避免使用湿布直接擦拭电子元件,防止短路。电池维护锂电池是无人机的核心部件,需避免过度放电或充电。长期存放时应保…

vlm MiniCPM 学习部署实战

目录 开源地址: 模型repo下载: 单图片demo: 多图推理demo: 论文学习笔记: 部署完整教程: 微调教程: 部署,微调教程,视频实测 BitCPM4 技术报告 创意&#xff1…

92套毕业相册PPT模版

致青春某大学同学聚会PPT模版,那些年我们一起走过的岁月PPT模版,某学院某班同学联谊会PPT模版,匆匆那年PPT模版,青春的纪念册PPT模版,栀子花开PPT模版,毕业纪念册PPT模版。 92套毕业相册PPT模版&#xff1…

爬虫基础概念

网络爬虫概述 概念 网络爬虫(Web Crawler),也称为网络蜘蛛(Web Spider)或机器人(Bot),是一种自动化程序,用于系统地浏览互联网并收集网页信息。它模拟人类浏览器行为&…

java8 stream流操作的flatMap

我们来详细解释一下 Java 8 Stream API 中的 flatMap 操作。理解 flatMap 的关键在于将其与 map 操作进行对比。​​核心概念:​​​​map 操作:​​作用:将一个流中的每个元素​​转换​​为另一个元素(类型可以不同)…

开源UI生态掘金:从Ant Design二次开发到行业专属组件的技术变现

开源UI生态掘金:从Ant Design二次开发到行业专属组件的技术变现内容摘要在开源UI生态中,Ant Design作为一款广受欢迎的UI框架,为开发者提供了强大的基础组件。然而,面对不同行业的特定需求,仅仅依靠现有的组件往往难以…

Object Sense (OSE):一款从编辑器脚本发展起来的编程语言

引言:从Vim编辑器走出的语言在编程语言的世界里,许多革命性的创新往往源于看似简单的工具。Object Sense(简称OSE)的诞生,便与一款经典文本编辑器——Vim息息相关。它的前身是Vim的脚本语言VimL(Vimscript&…

我考PostgreSQL中级专家证书二三事

1. 为什么选择PGCE?PostgreSQL的开源特性、高性能和高扩展性早已让我心生向往,而PGCE认证不仅是对技术能力的认可,更是一张通往更高职业舞台的“通行证”。官方资料提到,PGCE考试涵盖性能优化、高可用架构、复杂查询处理、内核原理…

Java 动态导出 Word 登记表:多人员、分页、动态表格的最佳实践

本文详细讲解如何使用 Java 动态导出包含多人员报名表的 Word 文档,每人占据独立一页,并支持动态表格行(如个人经历)。我们对比了多种实现方案,最终推荐基于 Freemarker XML 模板 或 docx4j 的灵活方式,并…

【element-ui el-table】多选表格勾选时默认勾选了全部,row-key绑定异常问题解决

项目场景: Element-UI的el-table组件row-key使用问题 同一个页面使用了几个table,这几个table都使用了多选,row-key属性,其中row-key的绑定方式都是用的静态绑定,row-key“username”或row-key“id”,可正常…

C#注释技巧与基础编程示例

以下是一个包含基础注释的 C# 程序示例&#xff0c;展示了 C# 中各类注释的使用方法&#xff1a;using System;namespace BasicCSharpProgram {/// <summary>/// Program 类是应用程序的入口点/// 包含 Main 方法作为程序执行的起点/// </summary>public class Pro…

极客大挑战2019-HTTP

涵盖知识&#xff1a;UA头伪造漏洞&#xff1a;全称&#xff1a;User-Agent 这个部分包含我们所使用的操作系统版本&#xff0c;cpu&#xff0c;浏览器类型等。来源伪造漏洞&#xff1a;在http请求头中会携带一个Referer&#xff0c;这个用来表示服务器用户是从哪个地方来的X-F…

谈谈ArrayList与Vector的理解?

目录 扩容机制 ArrayList扩容源码 Vector扩容源码 二者区别 扩展&#xff1a;stack(栈&#xff09; 1.创建stack对象 2. 入栈(先进后出&#xff09; 3.出栈 扩展&#xff1a;举个例子&#xff1a;实现下字符串逆置&#xff0c;利用stack栈来实现。 从接口实现上&#xff…

【Linux庖丁解牛】— 多线程同步 !

1. 什么是线程同步为什么会有线程同步&#xff0c;那一定是有了新问题。互斥可以解决临界资源被同时访问的问题&#xff0c;但是纯互斥也会带来新的问题。由于当前被执行的线程离cpu最近【其他线程被阻塞挂起还要被唤醒】&#xff0c;所以&#xff0c;当前进程对于竞争锁天然就…

基于arduino uno r3主控的环境监测系统设计-1

准备设计arduino uno r3为主控的环境监测系统&#xff0c;通过传感器采集TVOC&#xff08;总挥发性有机物&#xff09;、HCHO&#xff08;甲醛&#xff09;和eCO2&#xff08;等效二氧化碳&#xff09;数据&#xff0c;并显示在LCD屏幕上&#xff0c;同时支持数据记录到SD卡&am…

ITIL 4:云计算与微服务对组织架构的影响

这几年&#xff0c;很多组织在推进数字化转型时遇到一个共同的问题&#xff1a;业务节奏越来越快&#xff0c;但内部协作的“架构”却越来越跟不上节奏。技术架构的变革&#xff0c;必须同步推动组织架构的重塑。特别是随着云计算和微服务架构的广泛应用&#xff0c;这种影响愈…

【Android】xml和Java两种方式实现发送邮件页面

三三要成为安卓糕手 一&#xff1a;xml中LinearLayout布局参数的使用 1&#xff1a;xml代码 <?xml version"1.0" encoding"utf-8"?> <LinearLayout xmlns:android"http://schemas.android.com/apk/res/android"xmlns:app"http:/…