liu
3 天以前 a76bfe866c705285b737d593e8629a8be819b8f7
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
package cn.iocoder.yudao.server;
 
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Component;
 
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;
 
/**
 * 启动耗时监控:记录每个 Bean 的初始化耗时,启动完成后输出 Top 50 最慢的 Bean
 */
@Slf4j
@Component
public class StartupTimeMonitor implements BeanPostProcessor, ApplicationListener<ApplicationReadyEvent> {
 
    private final Map<String, Long> beanStartTime = new ConcurrentHashMap<>();
    private final Map<String, Long> beanDurations = new ConcurrentHashMap<>();
    private final AtomicInteger beanCount = new AtomicInteger(0);
 
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        beanStartTime.put(beanName, System.nanoTime());
        return bean;
    }
 
    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        Long start = beanStartTime.remove(beanName);
        if (start != null) {
            long duration = System.nanoTime() - start;
            if (duration > 1_000_000) { // 只记录 > 1ms 的
                beanDurations.put(beanName, duration);
            }
            beanCount.incrementAndGet();
        }
        return bean;
    }
 
    @Override
    public void onApplicationEvent(ApplicationReadyEvent event) {
        List<Map.Entry<String, Long>> sorted = new ArrayList<>(beanDurations.entrySet());
        sorted.sort(Map.Entry.<String, Long>comparingByValue().reversed());
 
        long totalMs = sorted.stream().mapToLong(Map.Entry::getValue).sum() / 1_000_000;
 
        log.info("========== 启动耗时分析 ==========");
        log.info("Bean 总数: {}, 初始化总耗时: {} 秒", beanCount.get(), totalMs / 1000.0);
        log.info("========== Top 50 最慢 Bean ==========");
 
        int topN = Math.min(50, sorted.size());
        for (int i = 0; i < topN; i++) {
            Map.Entry<String, Long> entry = sorted.get(i);
            double ms = entry.getValue() / 1_000_000.0;
            log.info(String.format("  %d. %s - %.1f 毫秒", i + 1, entry.getKey(), ms));
        }
        log.info("====================================");
    }
}