springboot随网页访问自动重启解决方案
springboot随网页访问自动重启问题解决
问题起因
应学校要求,制作学校课表时,在控制台日志发现springboot启动异常,每当网页访问或者刷新时,springboot自动重新启动,因此造成缓存工具类无法正常缓存(缓存数据在hashMap中,随着springboot重新启动自动初始化为null),定时器工作异常(定时器每刷新一次重复调用一次造成多个定时器同时工作),以及数据库连接池自动关闭(重复调用多个定时器使其中的jdbc线程数量耗尽线程池中资源)。这事拖不得,得赶紧看看。
筛查问题原因
- 根据网络资料查询,springboot自动重新启动的情况仅有一种,即热部署,当你的项目引入依赖
<dependency>
<groupid>org.springframework.boot</groupid>
<artifactid>spring-boot-devtools</artifactid>
<optional>true</optional>
</dependency>
之后,只要你对项目修改代码,项目便会重新加载,表现在控制台中便是又输出一个springboot日志,如图:
当你启动springboot时,此时时间为17:38。
热部署让你的项目自动重启,此时时间为17:39。
-
显然在本地试运行时,不可能每次都运行时修改自己代码,且运行多次后问题都存在。故原因不在运行后手动修改代码上,因此,我们把问题原因锁定在运行后自动修改的文件中,因此,锁定到生成网站访问量的txt文件中,文件相关代码如下:
@RequestMapping(value="/visitCount",method = RequestMethod.POST) @ResponseBody private String addVisitCount(){ //运用Ajax和注解使每次访问网站时自动调用该方法 long count; count = readFile();//读取文件中的访问量数据 count = count + 1;//访问量+1 writeFile(count);//写入文件 return "json"; }
由此我们可推测,每当我们访问网站时,都会重写一遍txt文件,故项目的文件遭到了修改,以此激发了热部署启动。
验证推测
我们把计数器暂时注释掉:
@RequestMapping(value="/visitCount",method = RequestMethod.POST)
@ResponseBody
private String addVisitCount(){ //运用Ajax和注解使每次访问网站时自动调用该方法
long count;
count = readFile();//读取文件中的访问量数据
count = count + 1;//访问量+1
// writeFile(count);//写入文件
return "json";
}
重新运行程序,此时程序正常运行。
问题分析
为什么txt的修改也会触发热部署?本人猜测原因如下:
txt文件在代码中路径为:
读取路径时,调用代码:
String fileName = VisitCount.class.getClassLoader().getResource("count.txt").getPath();
用该方法获得的路径实际为项目编译后生成的txt文件,如图:
即读写与更改都在编译后的class中实现,与原文件所在位置无关,因为是编译后的文件,所以在被修改后,触发了springboot的热部署,因每次访问网站都调用了addVisitCount方法修改了该文件,故造成每次刷新时项目自动初始化,因此产生一系列异常。
问题解决
在springboot的配置文件application.properties中加入如下代码,关闭修改代码立刻重启的热部署保证代码正确运行:
spring.devtools.restart.enabled = false
这是我的第一篇博客随笔,因对初学java,对热部署原理不甚理解,如有错误请评论指正。