springboot随网页访问自动重启解决方案

springboot随网页访问自动重启问题解决

问题起因

​ 应学校要求,制作学校课表时,在控制台日志发现springboot启动异常,每当网页访问或者刷新时,springboot自动重新启动,因此造成缓存工具类无法正常缓存(缓存数据在hashMap中,随着springboot重新启动自动初始化为null),定时器工作异常(定时器每刷新一次重复调用一次造成多个定时器同时工作),以及数据库连接池自动关闭(重复调用多个定时器使其中的jdbc线程数量耗尽线程池中资源)。这事拖不得,得赶紧看看。

筛查问题原因

  1. 根据网络资料查询,springboot自动重新启动的情况仅有一种,即热部署,当你的项目引入依赖
        <dependency>
            <groupid>org.springframework.boot</groupid>
            <artifactid>spring-boot-devtools</artifactid>
            <optional>true</optional>
        </dependency>

之后,只要你对项目修改代码,项目便会重新加载,表现在控制台中便是又输出一个springboot日志,如图:

当你启动springboot时,此时时间为17:38。

热部署让你的项目自动重启,此时时间为17:39。

  1. 显然在本地试运行时,不可能每次都运行时修改自己代码,且运行多次后问题都存在。故原因不在运行后手动修改代码上,因此,我们把问题原因锁定在运行后自动修改的文件中,因此,锁定到生成网站访问量的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,对热部署原理不甚理解,如有错误请评论指正。

posted @ 2021-08-03 18:16  易奔二  阅读(951)  评论(0编辑  收藏  举报