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

spring如何通过实现BeanPostProcessor接口计算并打印每一个bean的加载耗时

文章目录

      • 实现说明:
      • 注意事项:

要在Spring中通过BeanPostProcessor接口计算并打印每个Bean的加载耗时,我们可以利用该接口的两个回调方法记录Bean初始化前后的时间戳,然后计算时间差。

以下是实现方案:

  1. 首先创建一个实现BeanPostProcessor接口的类
  2. 使用线程安全的Map存储每个Bean的初始化开始时间
  3. postProcessBeforeInitialization中记录开始时间
  4. postProcessAfterInitialization中计算并打印耗时
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.stereotype.Component;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;/*** 计算并打印每个Bean的加载耗时*/
@Component
public class BeanInitializationTimer implements BeanPostProcessor {// 使用线程安全的Map存储Bean初始化开始时间private final Map<String, Long> startTimeMap = new ConcurrentHashMap<>();/*** Bean初始化之前调用,记录开始时间*/@Overridepublic Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {// 记录当前时间戳作为开始时间startTimeMap.put(beanName, System.currentTimeMillis());return bean;}/*** Bean初始化之后调用,计算并打印耗时*/@Overridepublic Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {// 获取开始时间Long startTime = startTimeMap.get(beanName);if (startTime != null) {// 计算耗时long endTime = System.currentTimeMillis();long duration = endTime - startTime;// 打印Bean加载耗时信息System.out.printf("Bean '%s' 初始化完成,类型: %s,耗时: %d ms%n",beanName, bean.getClass().getSimpleName(), duration);// 移除已处理的Bean记录,释放内存startTimeMap.remove(beanName);}return bean;}
}

实现说明:

  1. 组件注册:通过@Component注解将该处理器注册为Spring组件,Spring会自动发现并使用它
  2. 时间记录
  • postProcessBeforeInitialization方法中,记录每个Bean开始初始化的时间戳
  • 使用ConcurrentHashMap确保在多线程环境下的线程安全
  1. 耗时计算
  • postProcessAfterInitialization方法中,计算当前时间与开始时间的差值
  • 打印Bean名称、类型和初始化耗时
  • 处理完成后从Map中移除记录,避免内存泄漏
  1. 使用方式:只需将该类放入Spring扫描路径下,Spring容器启动时就会自动使用该处理器,无需额外配置

注意事项:

  • 该耗时包括Bean的初始化方法(如@PostConstruct标注的方法)执行时间
  • 如果Bean没有初始化方法,耗时会非常短
  • 对于懒加载的Bean,会在第一次被获取时才会计算耗时
  • 输出结果会显示在控制台,按Bean初始化完成的顺序打印

通过这种方式,你可以很方便地监控Spring容器中所有Bean的初始化性能,识别出初始化耗时较长的Bean,为性能优化提供依据。

http://www.dtcms.com/a/351268.html

相关文章:

  • 【数据结构】树和二叉树——二叉树
  • pytorch_grad_cam 库学习笔记—— Ablation-CAM 算法的基类 AblationCAM 和 AblationLayer
  • OneCode RAD:揭秘前端开发的配置化魔法
  • 【RAGFlow代码详解-14】知识图谱处理
  • Linux之SELinux 概述、SSH 密钥登录、服务器初始化
  • IUV5G专网排障(下)
  • 开源大模型本地部署
  • [Mysql数据库] 知识点总结3
  • 基于Android的电影院订票选座系统、基于Android的电影院管理系统app#基于Android的电影在线订票系统
  • 玩转QEMU硬件模拟器 - vexpress-a9开发板模拟开发
  • 深入浅出理解支持向量机:从原理到应用,解锁分类算法的核心密码
  • 宝石组合(蓝桥杯)
  • UX 设计入门终章:让洞察落地!用用户流程图、IA 和旅程图,设计用户与产品的互动故事
  • 介绍一下 bev fusion 网络结构
  • 微服务-27.配置管理-什么是配置管理
  • FULL OUTER JOIN 的作用与使用场景(检查表与表是否存在不同记录)
  • UML 时序图中交互片段操作符的详细解析与 C/C++ 实现示例
  • 五、VSCODE SSH连接linux服务器免密登录
  • Java中 0.05 + 0.01 ≠ 0.06 揭秘浮点数精度陷阱
  • VSCode: 从插件安装到配置,如何实现 Ctrl+S 保存时,完全按照 .eslintrc.js 中的 ESLint 规则自动格式化代码
  • vscode 配置 + androidStudio配置
  • Easy Voice Recorder Pro v2.9.3 简单易用的专业音频录制工具应用
  • 开发手札:UnrealEngine编辑器开发
  • 基于stm32的物联网OneNet火灾报警系统
  • Java面试指南‌——事务:数据库世界的超级英雄联盟
  • OpenSCA开源社区每日安全漏洞及投毒情报资讯|22th-24th Aug. , 2025
  • MySQL基本语法及与JAVA程序建立连接
  • 设计模式七大原则附C++正反例源码
  • 学习嵌入式的第三十八天
  • 【网络安全】XSS漏洞——PortSwigger靶场-DOM破坏