确认
当前程序版本
3.5.7
问题描述
我项目原先用的tkmybatis,然后在改成mybatis-plus后发现项目启动非常慢,依赖引入了mybatis-plus 3.5.7和mybatis-plus-join-boot-starter 1.4.13。通过BeanPostProcessor打印项目启动时的bean加载时间,发现所有mapper加载了两次,且第二次加载的时间非常缓慢,大概在一两千毫秒。
详细堆栈日志
2024-09-25 19:04:40.048 INFO 15620 --- [ main] c.d.c.BeanInitCostTimeBeanPostProcessor : beanName roomApRelMapper, init cost 2ms
2024-09-25 19:04:41.286 INFO 15620 --- [ main] c.d.c.BeanInitCostTimeBeanPostProcessor : beanName roomApRelMapper, init cost 1240ms
2024-09-25 19:04:41.777 INFO 15620 --- [ main] c.d.c.BeanInitCostTimeBeanPostProcessor : beanName roomApRelServiceImpl, init cost 487ms
2024-09-25 19:04:41.783 INFO 15620 --- [ main] c.d.c.BeanInitCostTimeBeanPostProcessor : beanName roomTcpRelMapper, init cost 1ms
2024-09-25 19:04:43.315 INFO 15620 --- [ main] c.d.c.BeanInitCostTimeBeanPostProcessor : beanName roomTcpRelMapper, init cost 1533ms
2024-09-25 19:04:43.320 INFO 15620 --- [ main] c.d.c.BeanInitCostTimeBeanPostProcessor : beanName tcpConfigMapper, init cost 1ms
2024-09-25 19:04:45.010 INFO 15620 --- [ main] c.d.c.BeanInitCostTimeBeanPostProcessor : beanName tcpConfigMapper, init cost 1691ms
2024-09-25 19:04:45.026 INFO 15620 --- [ main] c.d.c.BeanInitCostTimeBeanPostProcessor : beanName roomNodeRelMapper, init cost 1ms
2024-09-25 19:04:46.883 INFO 15620 --- [ main] c.d.c.BeanInitCostTimeBeanPostProcessor : beanName roomNodeRelMapper, init cost 1858ms
2024-09-25 19:04:46.887 INFO 15620 --- [ main] c.d.c.BeanInitCostTimeBeanPostProcessor : beanName nodeMapper, init cost 1ms
2024-09-25 19:04:49.114 INFO 15620 --- [ main] c.d.c.BeanInitCostTimeBeanPostProcessor : beanName nodeMapper, init cost 2228ms
2024-09-25 19:04:49.120 INFO 15620 --- [ main] c.d.c.BeanInitCostTimeBeanPostProcessor : beanName roomNodeLayoutMapper, init cost 0ms
2024-09-25 19:04:51.658 INFO 15620 --- [ main] c.d.c.BeanInitCostTimeBeanPostProcessor : beanName roomNodeLayoutMapper, init cost 2538ms
Comment From: fengyujun
是不是应该把mybatis-plus-join-boot-starter包去掉启动看看有没有问题,再确定是否是mp问题
Comment From: qmdx
up
Comment From: huangdinghe
会不会是读取hostname的问题
Comment From: H-Knight
是不是应该把mybatis-plus-join-boot-starter包去掉启动看看有没有问题,再确定是否是mp问题
去掉过,依然启动很慢
Comment From: H-Knight
会不会是读取hostname的问题
你说的读取hostname具体指的什么?
Comment From: huangdinghe
生成雪花id会用hostname
Comment From: H-Knight
生成雪花id会用hostname
没有,我的ID目前用的UUID,而且是项目启动的时候慢,应该跟这里没关系吧
Comment From: H-Knight
@Aspect @Component public class LogAspect {
private final ThreadLocal<LogCenter> logThreadLocal = new ThreadLocal<>();
@Autowired
private LogCenterService logCenterService;
@Autowired
private ThreadPoolTaskExecutor commonThreadPool;
@Pointcut("execution (public * com.dm.api.*.*.*(..))")
public void logAspect() {
}
@Before(value = "logAspect() && @annotation(log)")
public void doBefore(JoinPoint joinPoint, Log log) throws Throwable {
try {
LoginUserDetails loginUserDetails = (LoginUserDetails) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
HttpServletRequest request = ((ServletRequestAttributes) Objects
.requireNonNull(RequestContextHolder.getRequestAttributes())).getRequest();
// 参数名
String[] argNames = ((MethodSignature) joinPoint.getSignature()).getParameterNames();
// 参数值
Object[] args = joinPoint.getArgs();
Map<Object, Object> objectMap = new HashMap<>(16);
//joinPoint中的参数名与参数值一一对应,所以组装成map对象
for (int i = 0; i < argNames.length; i++) {
objectMap.put(argNames[i], args[i]);
}
//当前时间
Date nowDate = new Date();
String title = log.title();
LogEvent event = log.event();
String memo = log.memo();
String module = log.module();
LogLevel logLevel = LogLevel.info;
Integer readType = (Integer) objectMap.get("readType");
if (readType != null) {
String valueByCode = LogReadType.getValueByCode(readType);
title = valueByCode;
}
//方法调用参数
String argsStr = null;
//非文件类 保存参数
if (!log.event().equals(LogEvent.file)) {
argsStr = joinPoint.getArgs() == null || joinPoint.getArgs().length == 0 ? null : JSONObject.toJSONString(joinPoint.getArgs());
}
//当事件为保存时 判断是修改/添加
if (log.event() == LogEvent.save) {
//从参数中获取PKID 如果存在且不为空则认定为修改 否则新增
if (StringUtils.isNotEmpty(argsStr)) {
JSONObject arsgJson = JSONObject.parseObject(argsStr);
if (StringUtils.isNotEmpty(arsgJson.getString("PKID"))) {
event = LogEvent.add;
} else {
event = LogEvent.edit;
}
}
}
LogCenter logCenter = new LogCenter();
// 创建人信息请根据实际项目获取方式获取
logCenter.setLogMemo(memo);
logCenter.setLogEvent(event.getValue());
logCenter.setSourceModule(module);
logCenter.setLogTitle(title);
logCenter.setLogData(argsStr);
logCenter.setLogLevel(logLevel.getValue());
logCenter.setHostIp(ServletUtil.getClientIP(request));
logCenter.setOperateUserId(loginUserDetails.getUser().getPkid());
logCenter.setCreateTime(nowDate);
logThreadLocal.set(logCenter);
} catch (Exception e) {
}
}
@AfterReturning(pointcut = "logAspect()", returning = "ret")
public void doAfterReturning(Object ret) {
LogCenter logCenter = logThreadLocal.get();
if (logCenter != null) {
commonThreadPool.execute(new SaveLogThread(logCenter, logCenterService));
logThreadLocal.remove();
}
}
@AfterThrowing(pointcut = "logAspect()", throwing = "e")
public void doAfterThrowable(Throwable e) {
LogCenter logCenter = logThreadLocal.get();
if (logCenter != null) {
// 设置日志级别
if (e instanceof OtherException || e.getCause() instanceof OtherException) {
logCenter.setLogEvent(LogLevel.warning.getValue());
} else {
logCenter.setLogEvent(LogLevel.error.getValue());
}
logCenter.setLogTitle(e.getMessage());
commonThreadPool.execute(new SaveLogThread(logCenter, logCenterService));
logThreadLocal.remove();
}
}
private static class SaveLogThread extends Thread {
private final LogCenter logCenter;
private final LogCenterService logCenterService;
public SaveLogThread(LogCenter logCenter, LogCenterService logCenterService) {
this.logCenter = logCenter;
this.logCenterService = logCenterService;
}
@Override
public void run() {
logCenterService.save(logCenter);
}
}
} 我发现启动慢是因为这个切面导致的,我在去掉这个类后项目启动速度是正常的,一旦加上后,mapper初始化就会变得非常非常慢