gpt4 book ai didi

java - 获取 spring bean 初始化时间

转载 作者:塔克拉玛干 更新时间:2023-11-03 05:24:56 29 4
gpt4 key购买 nike

我有一个带有大型 spring 上下文的应用程序,它加载了很多开发人员编写的大量 bean。
一些 bean 可能会对其初始化代码进行一些重要的处理,这可能需要很长时间。
我正在寻找一种简单的方法来获取每个 bean 的加载时间。
由于该软件在大量客户的机器上运行,我需要一种方法来轻松地在日志中找到瓶颈 bean。
如果我可以注册到诸如“加载 bean 之前”和之后的事件,那就太好了。
因此,如果我能有问题地获取这些数据,我可以这样写:

if (beanLoadingTime > 2 seconds) 
print bean details and loading time to log file

这就是为什么启用日志记录或分析是不够的。

最佳答案

不知道我的解决方案是否对您有帮助,但这就是我所做的,因为我需要类似的东西。

首先,我们需要记录两件事,实例化时间和初始化时间。首先,我只为包“org.springframework.beans.factory”启用日志记录,使用 %d{mm:ss,SSS} %m%n 作为模式(仅限时间和消息)。 Spring 记录如下消息:Creating instance of bean... 和 Finished creating instance of bean... 对于第二件事,我按照 this answer 中的建议创建了一个 LoggerBeanPostProcessor。 .代码是:

public class LoggerBeanPostProcessor implements BeanPostProcessor, Ordered {

protected Log logger = LogFactory.getLog("org.springframework.beans.factory.LoggerBeanPostProcessor");
private Map<String, Long> start;
private Map<String, Long> end;

public LoggerBeanPostProcessor() {
start = new HashMap<>();
end = new HashMap<>();
}

@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
start.put(beanName, System.currentTimeMillis());
return bean;
}

@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
end.put(beanName, System.currentTimeMillis());
logger.debug("Init time for " + beanName + ": " + initializationTime(beanName));
return bean;
}

@Override
public int getOrder() {
return Integer.MAX_VALUE;
}

// this method returns initialization time of the bean.
public long initializationTime(String beanName) {
return end.get(beanName) - start.get(beanName);
}
}

我在 log4j 配置中使用文件附加程序。然后我写了一个简单的代码来解析该信息并获取每件事的毫秒数并将它们相加:

public static void main(String[] argumentos) throws Exception{
File file = new File("C:\\app\\daily.log");
List<String> lines = FileUtils.readLines(file);

Map<String,Long> start = new HashMap();
Map<String,Long> end = new HashMap();
Map<String,Long> init = new HashMap();
List<String> beans = new ArrayList();
int max = 0;

for(String line : lines) {
String time = StringUtils.substring(line, 0, 9);
String msg = StringUtils.substring(line, 10);

if(msg.startsWith("Creating instance")) {
int fi = StringUtils.indexOf(msg, '\'') + 1;
int li = StringUtils.lastIndexOf(msg, '\'');
String bean = StringUtils.substring(msg, fi, li);
if(start.containsKey(bean)) {
continue;
}
start.put(bean, parseTime(time));
beans.add(bean);
max = Math.max(max, bean.length());

} else if(msg.startsWith("Finished creating")) {
int fi = StringUtils.indexOf(msg, '\'') + 1;
int li = StringUtils.lastIndexOf(msg, '\'');
String bean = StringUtils.substring(msg, fi, li);
if(end.containsKey(bean)) {
continue;
}
end.put(bean, parseTime(time));

} else if(msg.startsWith("Init time for")) {
int li = StringUtils.lastIndexOf(msg, ':');
String bean = StringUtils.substring(msg, 14, li);
if(init.containsKey(bean)) {
continue;
}
init.put(bean, Long.parseLong(StringUtils.substring(msg, li+2)));
}
}

for(String bean : beans) {
long s = start.get(bean);
long e = end.get(bean);
long i = init.containsKey(bean) ? init.get(bean) : -1;
System.out.println(StringUtils.leftPad(bean, max) + ": " + StringUtils.leftPad(Long.toString((e-s)+i), 6, ' '));
}
}

结果是:

                                           splashScreen:    172
org.springframework.aop.config.internalAutoProxyCreator: 31
loggerBeanPostProcessor: 1137
appContext: 1122

希望这对你有帮助,就像对我有帮助一样。

关于java - 获取 spring bean 初始化时间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32422283/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com