项目中使用spring-boot-devtools,导致tk.mybatis加载数据库实体报错

网上找到的解决方案不能解决问题。最后定位为devtools开启导致的错误。配置文件中热部署生效:

spring.devtools.restart.enabled=true

定位到tk.mybatis框架,MapperCacheDisabler中该类作用初始化完成后,清空类信息的缓存,如果使用了 Devtools,会清除当前的ClassLoader,导致mapper最后找不到:

private void removeEntityHelperCache(Class<?> entityHelper) {
try {
Field cacheField = ReflectionUtils.findField(entityHelper, “entityTableMap”);
if (cacheField != null) {
ReflectionUtils.makeAccessible(cacheField);
Map cache = (Map) ReflectionUtils.getField(cacheField, null);
//如果使用了 Devtools,这里获取的就是当前的 RestartClassLoader
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
for (Object key : new ArrayList(cache.keySet())) {
Class entityClass = (Class) key;
//清理老的ClassLoader缓存的数据,避免测试环境溢出
if (!entityClass.getClassLoader().equals(classLoader)) {
cache.remove(entityClass);
}
}
logger.info(“Clear EntityHelper entityTableMap cache.”);
}
} catch (Exception ex) {
logger.warn(“Failed to disable Mapper MsUtil cache. ClassCastExceptions may occur”, ex);
}
}

MapperCacheDisabler由MapperAutoConfiguration注册bean对象,看到如下代码片段:

/**
* Support Devtools Restart.
*/
@org.springframework.context.annotation.Configuration
@ConditionalOnProperty(prefix = “spring.devtools.restart”, name = “enabled”, matchIfMissing = true)
static class RestartConfiguration {
@Bean
public MapperCacheDisabler mapperCacheDisabler() {
return new MapperCacheDisabler();
}
}

由此定位到问题,devtools开启热部署后,导致mapper缓存被清除。解决方案就是将开发的热部署关闭,配置文件中配置参数改为false:

spring.devtools.restart.enabled=false

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐