Spring Boot + devtools 轻松搞定热部署!

01、背景介绍

在软件项目的开发过程中,不可避免的会经常修改代码,每次修改代码,都需要手动停止然后再启动服务,最后验证代码的正确性。即使一个简单的静态资源文件的修改,也需要重启���整个过程其实非常耗时。

Spring 团队也注意到了这一点,为了加快项目的重启速度,Spring Boot 提供了一个开发者工具,它可以监控 classpath 路径上的文件,只要源码或者配置文件修改,Spring Boot 应用可以自动重启,更改后的代码自动生效,无需人工干预。

可以说,在开发阶段,这个功能非常实用。

今天通过这篇文章,我们一起来学习一下如何在 Spring Boot 中使用开发者工具。

02、启用开发者工具

下面,我们以Thymeleaf页面模板引擎为例,简单介绍静态资源文件和源代码的修改,Spring Boot 实现应用自动重启的方式。

2.1、添加相关依赖包

要使用开发者工具,首先需要在pom.xml中添加如下依赖包。

xml 复制代码
<!-- devtools热部署依赖 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-devtools</artifactId>
    <!-- 防止将依赖传递到其他模块中 -->
    <optional>true</optional>
</dependency>1.2.3.4.5.6.7.

2.2、添加相关配置参数

当项目添加devtools工具包之后,Spring Boot devtools 默认已经帮我们开启了应用自动重启特性,也开启禁止静态资源在浏览器缓存的属性,同时排除了特定的资源文件被修改时自动重启的操作。

例如,默认情况下,Spring Boot devtools 对如下的资源目录文件变更,不会触发自动重启。

markdown 复制代码
META-INF/maven/**,META-INF/resources/**,resources/**,static/**,public/**,templates/**,**/*Test.class,**/*Tests.class,git.properties,META-INF/build-info.properties1.

这些目录通常用于存放静态资源,由于 spring-boot-devtools 工具默认开启了禁用缓存的操作,当文件发生修改时可以实时更新,无需重启应用。

当然,我们也可以在application.properties全局文件中指定配置,比如只排除/static、/public和/templates 目录中的文件修改重启操作,额外监控src/main/java目录下的文件修改时自动重启应用。

示例如下:

ini 复制代码
# 开启热部署(更改文件后,自动重启)
spring.devtools.restart.enabled=true
# 设置哪些资源变动后不触发自动重启,会覆盖默认的exclude内容(资源不会触发重启,但会触发实时重新加载)
spring.devtools.restart.exclude=static/**,public/**,templates/**
# 设置需要监控额外的路径,当内容发生变化会出发自动重启(优先于exclude)
spring.devtools.restart.additional-paths=src/main/java1.2.3.4.5.6.

2.3、IDEA 配置

完成以上的配置之后,当修改代码时,可能服务还是无法实现自动重启的效果。

如果你采用的是 IDEA 开发工具,此时还需要配合 IDEA 相关设置,开启运行时编译。

实现步骤如下!

2.3.1、设置1

在File->Setting->Build,Execution,Deployment->Compile操作路径下,勾选Make project automatically。

2.3.2、设置2

同时按住ctrl+alt+shift+/,选择Registry,找到compiler.automake.allow.when.app.running配置,并将其勾选上。

2.4、开启 fork 配置(选)

通过以上的设置之后,如果热部署服务依然不能生效,可以在spring-boot-maven-plugin插件中,增加true参数配置,明确启用热部署功能。

xml 复制代码
<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
            <configuration>
                <!-- 启用热部署功能(如果devtools不生效) -->
                <fork>true</fork>
            </configuration>
        </plugin>
    </plugins>
</build>1.2.3.4.5.6.7.8.9.10.11.12.

大部分情况下,经过实测,没有这个配置也可以实现自动重启服务,具体以实际情况而定。

2.5、观察热部署效果

完成以上的操作之后,下面我们编写一个用例,验证一下服务自动重启效果。

首先,在templates目录下创建一个index.html静态页面,内容如下:

xml 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <p th:text="${content}">内容替换</p>
</body>
</html>1.2.3.4.5.6.7.8.9.10.

接着,创建一个视图接口,内容如下:

kotlin 复制代码
@Controller
public class HelloController {

    @GetMapping("/")
    public String index(ModelMap map) {
        // 绑定元素
        map.addAttribute("content", "Hello World");
        return "index";
    }
}1.2.3.4.5.6.7.8.9.10.

最后,启动服务,在浏览器中访问http://localhost:8080/。

修改接口返回的数据为Hello World gogo,服务会自动重启,重新访问页面后的效果。

在index.html静态页面中增加

修改静态页面代码

,此时服务不会自动重启,重新访问页面后的效果。

03、关闭开发者工具

devtools 只适用于开发环境,线上环境不可开启。在上生产的时候,我们希望将其关闭,如何处理呢?

最简单粗暴的方法,就是将其引用排除,可以根治很多问题!

当然也有另一种办法,可以在application.properties配置文件中禁止自动重启服务,比如添加如下参数配置。

ini 复制代码
spring.devtools.restart.enabled=false1.

也可以在启动命令中增加-Dspring.devtools.restart.enabled=false参数来进行关闭。

自动重启将不再被触发,但是仍将使用自动重启类加载器。如果你想完全禁用类加载器,可以在启动应用程序之前强制设置,示例如下。

arduino 复制代码
public static void main(String[] args) {
    System.setProperty("spring.devtools.restart.enabled", "false");
    SpringApplication.run(Application.class, args);
}1.2.3.4.

04、小结

最后总结一下,采用 Spring Boot devtools 开发者工具,当修改代码时,无需手动重启服务,即可实现代码实时更新,并且应用自动重启速度也很快,对于开发者非常友好。

之所以能实现这样的效果,Spring Boot devtools 使用了两个类加载来处理自动重启的问题。

对于不会变化的类,例如 Spring 本身的引用包和第三方引用的 jar 包,使用一个 base classloader 加载器来加载;对于正在开发中的类,则使用 restart classloader 加载器来进行加载。

同时,后台启动一个文件监听线程(File Watcher),监测目录中的类发生变动时,原来的 restart ClassLoader 将被丢弃,并产生一个新的 restart ClassLoader 来进行加载。因此,这种模式下自动重启会比冷启动快一些,因为 base classloader 已经准备好了无需重启。

相关推荐
骆晨学长26 分钟前
基于springboot的智慧社区微信小程序
java·数据库·spring boot·后端·微信小程序·小程序
AskHarries31 分钟前
利用反射实现动态代理
java·后端·reflect
bjzhang7533 分钟前
SpringBoot开发——整合SpringDoc实现在线接口文档
spring boot·springdoc
Flying_Fish_roe1 小时前
Spring Boot-Session管理问题
java·spring boot·后端
赚钱给孩子买茅台喝1 小时前
智能BI项目第四期
java·spring boot·spring cloud·aigc
hai405872 小时前
Spring Boot中的响应与分层解耦架构
spring boot·后端·架构
Adolf_19933 小时前
Flask-JWT-Extended登录验证, 不用自定义
后端·python·flask
叫我:松哥3 小时前
基于Python flask的医院管理学院,医生能够增加/删除/修改/删除病人的数据信息,有可视化分析
javascript·后端·python·mysql·信息可视化·flask·bootstrap
海里真的有鱼3 小时前
Spring Boot 项目中整合 RabbitMQ,使用死信队列(Dead Letter Exchange, DLX)实现延迟队列功能
开发语言·后端·rabbitmq
工业甲酰苯胺3 小时前
Spring Boot 整合 MyBatis 的详细步骤(两种方式)
spring boot·后端·mybatis