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

【Spring篇】Spring的生命周期

一、Bean 生命周期的核心阶段

1. 实例化(Instantiation)

触发时机:容器启动时(单例 Bean)或请求时(原型 Bean)。
实现方式
通过反射(Class.newInstance() 或构造器)创建 Bean 的实例。

2. 属性赋值(Population)

依赖注入
通过字段注入(@Autowired)、Setter 注入或构造器注入为 Bean 的属性赋值。
处理 Aware 接口
若 Bean 实现了 BeanNameAwareBeanFactoryAware 等接口,容器会回调对应方法。

public class MyBean implements BeanNameAware {private String beanName;@Overridepublic void setBeanName(String name) {this.beanName = name; // 获取 Bean 的名称}
}
3. BeanPostProcessor 的前置处理

调用 postProcessBeforeInitialization
在 Bean 初始化前执行自定义逻辑(如修改 Bean 属性)。

public class MyBeanPostProcessor implements BeanPostProcessor {@Overridepublic Object postProcessBeforeInitialization(Object bean, String beanName) {// 对 Bean 进行前置处理return bean;}
}
4. 初始化(Initialization)

@PostConstruct 注解方法
标记在方法上,容器会调用该方法。

@PostConstruct
public void init() {// 初始化逻辑
}

InitializingBean 接口
实现 afterPropertiesSet() 方法。

public class MyBean implements InitializingBean {@Overridepublic void afterPropertiesSet() {// 属性赋值完成后执行}
}

XML 配置的 init-method
在 XML 中指定初始化方法。

<bean id="myBean" class="com.example.MyBean" init-method="customInit"/>
5. BeanPostProcessor 的后置处理

调用 postProcessAfterInitialization
在 Bean 初始化后执行自定义逻辑(如生成代理对象)。

@Override
public Object postProcessAfterInitialization(Object bean, String beanName) {// 对 Bean 进行后置处理(如 AOP 代理)return bean;
}
6. Bean 就绪(In Use)

业务使用阶段
Bean 被应用程序代码调用,执行业务逻辑。

7. 销毁(Destruction)

@PreDestroy 注解方法
标记在方法上,容器销毁前调用。

@PreDestroy
public void cleanup() {// 释放资源逻辑
}

DisposableBean 接口
实现 destroy() 方法。

public class MyBean implements DisposableBean {@Overridepublic void destroy() {// 容器销毁时执行}
}

XML 配置的 destroy-method
在 XML 中指定销毁方法。

<bean id="myBean" class="com.example.MyBean" destroy-method="customDestroy"/>

二、生命周期的完整流程图

实例化 → 属性赋值 → BeanPostProcessor前置处理 → 初始化 → BeanPostProcessor后置处理 → 使用 → 销毁

三、扩展点与高级特性

1. Aware 接口

作用:让 Bean 感知容器环境。
常见接口
BeanNameAware:获取 Bean 的名称。
BeanFactoryAware:获取 BeanFactory 引用。
ApplicationContextAware:获取 ApplicationContext 引用。

2. BeanPostProcessor

核心用途
在 Bean 初始化前后插入自定义逻辑(如 AOP 代理、属性加密)。
典型场景
Spring AOP 通过 AbstractAutoProxyCreator(BeanPostProcessor 的子类)生成代理对象。

3. BeanFactoryPostProcessor

作用
在 Bean 定义加载后、实例化前修改 Bean 的定义(如修改属性值)。

public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {@Overridepublic void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {BeanDefinition beanDef = beanFactory.getBeanDefinition("myBean");beanDef.getPropertyValues().add("property", "newValue");}
}
4. 作用域对生命周期的影响

单例(Singleton)
容器启动时创建,容器关闭时销毁。
原型(Prototype)
每次请求时创建,容器不管理其销毁。
其他作用域
Request/Session(Web 环境):生命周期与请求或会话绑定。
自定义作用域:通过 Scope 接口扩展。


四、示例代码:完整生命周期演示

1. Bean 类
public class LifecycleBean implements BeanNameAware, InitializingBean, DisposableBean {private String beanName;@Overridepublic void setBeanName(String name) {this.beanName = name; // BeanNameAware 回调}@PostConstructpublic void postConstruct() {System.out.println("@PostConstruct 方法调用");}@Overridepublic void afterPropertiesSet() {System.out.println("InitializingBean.afterPropertiesSet() 调用");}public void customInit() {System.out.println("XML init-method 调用");}@PreDestroypublic void preDestroy() {System.out.println("@PreDestroy 方法调用");}@Overridepublic void destroy() {System.out.println("DisposableBean.destroy() 调用");}public void customDestroy() {System.out.println("XML destroy-method 调用");}
}
2. BeanPostProcessor
public class CustomBeanPostProcessor implements BeanPostProcessor {@Overridepublic Object postProcessBeforeInitialization(Object bean, String beanName) {if (bean instanceof LifecycleBean) {System.out.println("BeanPostProcessor.postProcessBeforeInitialization() 调用");}return bean;}@Overridepublic Object postProcessAfterInitialization(Object bean, String beanName) {if (bean instanceof LifecycleBean) {System.out.println("BeanPostProcessor.postProcessAfterInitialization() 调用");}return bean;}
}
3. 输出结果
实例化 LifecycleBean
BeanNameAware.setBeanName() 调用
BeanPostProcessor.postProcessBeforeInitialization() 调用
@PostConstruct 方法调用
InitializingBean.afterPropertiesSet() 调用
XML init-method 调用
BeanPostProcessor.postProcessAfterInitialization() 调用
...(Bean 使用阶段)...
@PreDestroy 方法调用
DisposableBean.destroy() 调用
XML destroy-method 调用

五、总结

  1. 核心阶段:实例化 → 属性注入 → 初始化 → 销毁。
  2. 关键扩展点
    • Aware 接口(获取容器信息)。
    BeanPostProcessor(初始化前后处理)。
    @PostConstruct/@PreDestroy(注解回调)。
    InitializingBean/DisposableBean(接口回调)。
  3. 作用域影响:单例和原型 Bean 的生命周期差异。
  4. 设计思想:通过回调接口和扩展点实现松耦合和可定制化。

通过掌握 Bean 的生命周期,可以更好地利用 Spring 的扩展能力(如自定义初始化、资源管理),同时避免因生命周期管理不当导致的资源泄漏或状态错误。

相关文章:

【Spring篇】Spring的生命周期

一、Bean 生命周期的核心阶段 1. 实例化&#xff08;Instantiation&#xff09; • 触发时机&#xff1a;容器启动时&#xff08;单例 Bean&#xff09;或请求时&#xff08;原型 Bean&#xff09;。 • 实现方式&#xff1a; 通过反射&#xff08;Class.newInstance() 或构造…...

C# 的Lambda表达式‌常见用法和示例

C# 的 ‌Lambda 表达式‌是一种强大的语法糖&#xff0c;能够极大简化代码并增强灵活性。以下是它的主要功能和应用场景&#xff0c;结合具体示例说明&#xff1a; 1. ‌简化委托实例化‌ Lambda 可以快速定义委托&#xff08;如 Func、Action&#xff09;&#xff0c;无需显式…...

C++学习之路:从头搞懂配置VScode开发环境的逻辑与步骤

目录 编辑器与IDE基于vscode的C开发环境配置1. 下载vscode、浅尝编译。番外篇 2. 安装插件&#xff0c;赋能编程。3. 各种json文件的作用。c_cpp_properties.jsontask.jsonlaunch.json 总结&&彩蛋 编辑器与IDE 上一篇博客已经介绍过了C程序的一个编译流程&#xff0c;从…...

Web3与网络安全:如何确保去中心化应用的安全性

Web3与网络安全&#xff1a;如何确保去中心化应用的安全性 随着区块链技术的蓬勃发展&#xff0c;Web3的概念逐渐成为互联网发展的新趋势。Web3强调去中心化、用户主权和数据隐私&#xff0c;它的核心是构建一个更加开放、透明和安全的网络环境。然而&#xff0c;随着去中心化…...

插值法笔记 ——武汉理工统计 周

第二章 插值法 插值法定义 插值函数定义 设函数 y f ( x ) y f(x) yf(x) 在区间 [a,b] 上有定义&#xff0c;且满足节点排列&#xff1a; a ≤ x 0 < x 1 < ⋯ < x n ≤ b a \leq x_0 < x_1 < \cdots < x_n \leq b a≤x0​<x1​<⋯<xn​≤b …...

23种设计模式-命令(Command)设计模式

命令设计模式 &#x1f6a9;什么是命令设计模式&#xff1f;&#x1f6a9;命令设计模式的特点&#x1f6a9;命令设计模式的结构&#x1f6a9;命令设计模式的优缺点&#x1f6a9;命令设计模式的Java实现&#x1f6a9;代码总结&#x1f6a9;总结 &#x1f6a9;什么是命令设计模式…...

和鲸科技执行总裁殷自强受邀主讲华中附属同济医院大模型应用通识首期课程

当前&#xff0c;医学与人工智能的深度融合正迎来历史性发展机遇。华中科技大学同济医学院附属同济医院&#xff08;以下简称“同济医院”&#xff09;作为医疗人工智能应用的先行探索者&#xff0c;已在电子病历辅助书写、科研数据分析、医疗合同自动化审核等关键场景完成试点…...

CI/CD(三) 安装nfs并指定k8s默认storageClass

一、NFS 服务端安装&#xff08;主节点 10.60.0.20&#xff09; 1. 安装 NFS 服务端 sudo apt update sudo apt install -y nfs-kernel-server 2. 创建共享目录并配置权限 sudo mkdir -p /data/k8s sudo chown nobody:nogroup /data/k8s # 允许匿名访问 sudo chmod 777 /dat…...

Centos 7 安装VNC服务

Centos 7 安装VNC服务 1. 安装 TigerVNC2. 设置 VNC 密码3. 创建并配置 x0vncserver 服务4. 启用并启动服务5. 检查服务状态6. 配置防火墙7. 连接 VNC问题1:出现无法安装可能是镜像源导致的。手动配置镜像源清除 YUM 缓存并重新加载 1. 安装 TigerVNC 确保已安装 TigerVNC 服务…...

使用 Go 构建 MCP Server

一个互联网技术玩家&#xff0c;一个爱聊技术的家伙。在工作和学习中不断思考&#xff0c;把这些思考总结出来&#xff0c;并分享&#xff0c;和大家一起交流进步。 一、MCP 介绍 1. 基本介绍 MCP&#xff08;Model Context Protocol&#xff0c;模型上下文协议&#xff09;是…...

C语言贪吃蛇实现

When the night gets dark,remember that the Sun is also a star. 当夜幕降临时&#xff0c;请记住太阳也是一颗星星。 ————《去月球海滩篇》 目录 文章目录 一、《贪吃蛇》游戏介绍 二、WIN32部分接口简单介绍 2.1 控制台窗口大小设置 2.2 命令行窗口的名称的变更 2…...

pytorch小记(十五):pytorch中 交叉熵损失详解:为什么logits比targets多一个维度?

pytorch小记&#xff08;十五&#xff09;&#xff1a;pytorch中 交叉熵损失详解&#xff1a;为什么logits比targets多一个维度&#xff1f; PyTorch交叉熵损失详解&#xff1a;为什么logits比targets多一个维度&#xff1f;一、前言&#xff1a;新手常见困惑二、核心概念&…...

利用zabbix自带key获取数据

获取数据的三种方法 1、链接模版 服务器系统自身的监控 CPU CPU使用率、CPU负载 内存 内存剩余量 硬盘 关键性硬盘的剩余量、IO 网卡 流量/IO&#xff08;流入流量、流出流量、总流量、错误数据包流量&#xff09; 进程数 用户数 2、利用zabbix自带的键值key 1&#xff09;监…...

无人机数据处理系统设计要点与难点!

一、系统设计要点 无人机数据处理系统需要高效、可靠、低延迟地处理多源异构数据&#xff08;如影像、传感器数据、位置信息等&#xff09;&#xff0c;同时支持实时分析和长期存储。以下是核心设计要点&#xff1a; 1.数据采集与预处理 多传感器融合&#xff1a;集成摄像头…...

最大异或对 The XOR Largest Pair

题目来自洛谷网站&#xff1a; 思路&#xff1a; 两个循环时间复杂度太高了&#xff0c;会超时。 我们可以先将读入的数字&#xff0c;插入到字典树中&#xff0c;从高位到低位。对每个数查询的时候&#xff0c;题目要求是最大的异或对&#xff0c;所以我们选择相反的路径&am…...

基于SpringBoot + Vue 的汽车租赁管理系统

技术介绍&#xff1a; ①&#xff1a;架构: B/S、MVC ②&#xff1a;系统环境&#xff1a;Windows/Mac ③&#xff1a;开发环境&#xff1a;IDEA、JDK1.8、Maven、Mysql ④&#xff1a;技术栈&#xff1a;Java、Mysql、SpringBoot、Mybatis、Vue 项目功能&#xff1a; 角色&am…...

基于DrissionPage的TB商品信息采集与可视化分析

一、项目背景 随着电子商务的快速发展,淘宝作为中国最大的电商平台之一,拥有海量的商品信息。这些数据对于市场分析、用户行为研究以及竞争情报收集具有重要意义。然而,由于淘宝的反爬虫机制和复杂的页面结构,直接获取商品信息并不容易。尤其是在电商行业高速发展的今天,商…...

电气、电子信息与通信工程的探索与应用

从传统定义来看&#xff0c;电气工程是现代科技领域的核心学科和关键学科。它涵盖了创造产生电气与电子系统的有关学科的总和。然而&#xff0c;随着科学技术的飞速发展&#xff0c;电气工程的概念已经远超出这一范畴。 电子信息工程则是将电子技术、通信技术、计算机技术等应…...

Python备赛笔记2

1.区间求和 题目描述 给定a1……an一共N个整数&#xff0c;有M次查询&#xff0c;每次需要查询区间【L,R】的和。 输入描述: 第一行包含两个数&#xff1a;N,M 第二行输入N个整数 接下来的M行&#xff0c;每行有两个整数&#xff0c;L R&#xff0c;中间用空格隔开&…...

HTML5 拖放(Drag and Drop)学习笔记

一、HTML5 拖放简介 HTML5 拖放&#xff08;Drag and Drop&#xff09;是HTML5标准的一部分&#xff0c;允许用户抓取一个对象并将其拖动到另一个位置。拖放功能在现代网页中非常常见&#xff0c;例如文件上传、任务管理、布局调整等场景。 HTML5 拖放功能支持以下浏览器&…...

Sass (Scss) 与 Less 的区别与选择

Sass 与 Less 的区别与选择 1. 语法差异2. 特性与支持3. 兼容性4. 选择建议 在前端开发中&#xff0c;CSS预处理器如Sass&#xff08;Syntactically Awesome Stylesheets&#xff09;和Less被广泛使用&#xff0c;它们通过引入变量、嵌套规则、混合、函数等特性&#xff0c;使C…...

Unity2022发布Webgl2微信小游戏部分真机黑屏

复现规律&#xff1a; Unity PlayerSetting中取消勾选ShowSplashScreen 分析&#xff1a; 在Unity中&#xff0c;Splash Screen&#xff08;启动画面&#xff09; 不仅是视觉上的加载动画&#xff0c;还承担了关键的引擎初始化、资源预加载和渲染环境准备等底层逻辑。禁用后导…...

记一次线上SQL死锁事故

一、 引言 SQL死锁是一个常见且复杂的并发控制问题。当多个事务在数据库中互相等待对方释放锁时&#xff0c;就会形成死锁&#xff0c;从而导致事务无法继续执行&#xff0c;影响系统的性能和可用性。死锁不仅会导致数据库操作的阻塞&#xff0c;增加延迟&#xff0c;还可能对…...

Java并发编程 什么是分布式锁 跟其他的锁有什么区别 底层原理 实战讲解

目录 一、分布式锁的定义与核心作用 二、分布式锁与普通锁的核心区别 三、分布式锁的底层原理与实现方式 1. 核心实现原理 2. 主流实现方案对比 3. 关键技术细节 四、典型问题与解决方案 五、总结 六、具体代码实现 一、分布式锁的定义与核心作用 分布式锁是一种在分布…...

【react】在react中async/await一般用来实现什么功能

目录 基本概念 工作原理 优点 注意事项 底层原理 实际应用场景 1. 数据获取 (API 请求) 2. 表单提交 3. 异步状态管理 4. 异步路由切换 5. 异步数据预加载 6. 第三方 API 调用 7. 文件上传/下载 8. 路由导航拦截 关键注意事项 基本概念 async 函数&#xff1a;用…...

Axure项目实战:智慧城市APP(六)市民互动(动态面板、显示与隐藏)

亲爱的小伙伴&#xff0c;在您浏览之前&#xff0c;烦请关注一下&#xff0c;在此深表感谢&#xff01; 课程主题&#xff1a;市民互动 主要内容&#xff1a;动态面板、显示与隐藏交互应用 应用场景&#xff1a;AI产品交互、互动类应用 案例展示&#xff1a; 案例视频&am…...

为何服务器监听异常?

报错&#xff1a; 执行./RCF后出现监听异常--在切换网络后&#xff0c;由于前面没有退出./RCF执行状态&#xff1b;重新连接后&#xff0c;会出现服务器监听异常 原因如下&#xff1a; 由于刚开始登录内网&#xff0c;切换之后再重新登录内网&#xff0c;并且切换网络的过程中…...

1.认识Excel

一 Excel 可以用来做什么 二 提升技巧 1.数据太多 2.计算太累 3.提升数据的价值和意义 4.团队协作 三 学习目标 学习目标不是为了掌握所有的技能&#xff0c;追逐新功能。而是学知识来解决需求&#xff0c;如果之前的技能和新出的技能都可以解决问题&#xff0c;那不学新技能也…...

目标跟踪——deepsort算法详细阐述

deepsort 算法详解 Unmatched Tracks(未匹配的轨迹) 本质角色: 是已存在的轨迹在当前帧中“失联”的状态,即预测位置与检测结果不匹配。 生命周期阶段: 已初始化: 轨迹已存在多帧,可能携带历史信息(如外观特征、运动模型)。 未被观测到: 当前帧中未找到对应的检测框…...

AI Agent 是什么?从 Chatbot 到自动化 Agent(LangChain、AutoGPT、BabyAGI)

1. 引言:AI Agent 的演进 AI Agent(人工智能智能体)是 AI 发展的重要方向之一。早期的 AI 主要以 Chatbot 形式存在,如客服机器人、智能助手等,主要基于 NLP 技术进行任务处理。而随着大模型(LLM)能力的提升,AI Agent 逐步演进为能够自主执行任务的智能体,如 AutoGPT…...