通过BeanPostProcessor统计每一个Bean初始化耗时|通过优先级队列PriorityQueue构建小顶堆获取动态添加数列的TopK算法

通过BeanPostProcessor统计每一个Bean初始化耗时

思路:

  • 统计Bean耗时的基础数据结构是个Map,Map的键是Bean的名称,值是初始化耗费时间。
  • postProcessBeforeInitialization在Bean初始化之前执行,因此记录初始化开始时间
  • postProcessAfterInitialization在Bean初始化之后执行,因此通过初始化结束时间减去初始化开始时间得出初始化耗时
  • 通过监听ContextRefreshedEvent事件判断容器加载完毕,将最耗时的K个Bean日志输出。

通过优先级队列构建小顶堆获取动态添加数列的最大TopK个值

使用PriorityQueue构建TopK算法找出容器中初始化最耗时的K个Bean

思路:

  • 添加新数据进来,将新数据和堆顶的最小值进行比较
  • 新数据比堆顶最小值大,新数据得到晋升,抛弃堆顶最小值
  • 新数据比堆顶最小值小,忽略新数据,堆保持不变

代码示例

使用BeanPostProcessor统计每个Bean的耗时
public class LoggerBeanLoadCostPostProcessor implements BeanPostProcessor, Ordered, ApplicationListener<ContextRefreshedEvent> {
   

    private Map<String, Long> cost = new HashMap<>(500);

    private static final int TOPK = 5;

    private static AtomicInteger beanCount = new AtomicInteger(0);

    private TopK<CostInfo> topK = new TopK<>(TOPK);

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
   
        cost.put(beanName, Instant.now().toEpochMilli());
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
   
        beanCount.incrementAndGet();

        Long startStamp = cost.get(beanName);
        if (startStamp != null) {
   
            Long currentCost = Instant.now().toEpochMilli
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值