查看原文
其他

Spring Boot3.3 + devtools 轻松搞定热部署!

编程疏影 路条编程
2024-09-05


Spring Boot3.3 + devtools 轻松搞定热部署!

在当今复杂的软件项目开发进程中,代码的修改是一项频繁且不可避免的操作。每当开发者对代码进行调整,无论是对核心业务逻辑的优化,还是对界面展示细节的微调,都需要经历一个颇为繁琐的流程。

传统的方式是,开发者在完成代码修改后,必须手动停止正在运行的服务,然后重新启动服务,最后才能验证所做修改的正确性。这一过程不仅需要耗费大量的时间,还容易打断开发者的思路,降低开发效率。

即便是对一个看似简单的静态资源文件,如图片、CSS 样式表或 JavaScript 文件的修改,也无一例外地需要执行上述的停止-启动-验证流程。这种重复性的操作,对于开发者来说,无疑是一种巨大的时间浪费。

想象一下,在一个紧张的开发周期中,每一次微小的代码改动都伴随着漫长的等待和繁琐的操作,这将极大地影响项目的进度和开发者的积极性。

Spring 团队敏锐地察觉到了这一问题对开发效率造成的严重影响。为了给开发者提供更流畅、高效的开发体验,Spring Boot 推出了开发者工具。这一工具的核心功能在于能够实时监控 classpath 路径上的文件变化。只要源代码或者配置文件发生修改,Spring Boot 应用能够迅速自动重启,使得修改后的代码立即生效,全程无需人工干预。

可以说,在紧张而又充满挑战的开发阶段,这样的功能无疑是开发者的得力助手,极大地提升了开发效率,缩短了项目周期。

今天通过这篇文章,我们一同来学习怎样在 Spring Boot 中运用开发者工具。

启用开发者工具

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

添加相关依赖包

要使用开发者工具,首先要在 pom.xml 中添加如下依赖包。下面是项目的 pom.xml 文件:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.3.2</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.icoderoad</groupId>
<artifactId>spring-boot-devtools-example</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>spring-boot-devtools-example</name>
<description>Demo project for Spring Boot devtools</description>

<properties>
<java.version>17</java.version>
</properties>

<dependencies>
<!-- devtools 热部署依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>

<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>

</project>

添加相关配置参数

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

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

META-INF/maven/**,META-INF/resources/**,resources/**,static/**,public/**,templates/**,**/*Test.class,**/*Tests.class,git.properties,META-INF/build-info.properties

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

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

示例如下:

server.port=8080
spring.application.name=spring-boot-devtools-example

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

Eclipse 配置

完成上述配置后,修改代码时,服务可能仍无法实现自动重启。

如果使用的是 Eclipse 开发工具,需要进行以下相关设置,开启运行时编译。

实现步骤如下!

设置

在菜单 Project 中,找到编译相关的选项,勾选“Build Automatically”。

debug 启动 Spring Boot 项目的时候会进入 SilentExitExceptionHandler.exitCurrentThread 方法

解决方案

window → Preferences → Java → Debug → 取消勾选 Suspend execution on uncaught exceptions

开启 fork 配置(可选)

经过上述设置,如果热部署服务仍未生效,可以在 spring-boot-maven-plugin 插件中,增加<fork>true</fork>参数配置,明确启用热部署功能。

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

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

观察热部署效果

完成上述操作后,下面编写一个示例,验证服务自动重启效果。

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

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script>
</head>
<body >
<div class="alert alert-info" th:text="${content}">热部署效果测试,此内容会变 Controller 类设置替换</div>
</body>
</html>

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

package com.icoderoad.spring_boot_devtools_example.controller;

import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.GetMapping;

@Controller
public class IndexController {

@GetMapping("/")
public String index(ModelMap map) {
// 绑定元素
map.addAttribute("content", "热部署效果测试,Controller 类替换内容!");
return "index";
}
}

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

修改接口返回的数据为“修改》》》热部署效果测试,Controller 类替换内容!”,服务会自动重启,重新访问页面能看到效果。

在 index.html 静态页面中增加如下样式:

.center-div {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
</style>

div 元素修改为:

<div class="alert alert-info center-div" th:text="${content}">热部署效果测试,此内容会变 Controller 类设置替换</div>

此时服务不会自动重启,重新访问页面能看到效果。

关闭开发者工具

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

最直接的方法,就是将其引用排除,可以解决很多问题!

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

spring.devtools.restart.enabled=false

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

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

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

总结:

综上所述,Spring Boot devtools 开发者工具在代码修改时能够实现实时更新,无需手动重启服务,应用自动重启迅速,显著提升了开发者的工作效率。其之所以能达成如此高效的效果,关键在于巧妙运用了两个类加载器来处理自动重启。对于稳定不变的类,如 Spring 自身的引用包及第三方的 jar 包,通过 base classloader 加载;而对于正在开发中的类,则利用 restart classloader 加载。此外,后台启动的文件监听线程(File Watcher)能够实时监测目录中类的变动,一旦发生变化,会丢弃原有的 restart ClassLoader 并生成新的进行加载。正是这种机制,使得自动重启相较于冷启动更为快捷,因为 base classloader 已提前准备就绪,无需重复操作。

今天就讲到这里,如果有问题需要咨询,大家可以直接留言或扫下方二维码来知识星球找我,我们会尽力为你解答。


AI资源聚合站已经正式上线,该平台不仅仅是一个AI资源聚合站,更是一个为追求知识深度和广度的人们打造的智慧聚集地。通过访问 AI 资源聚合网站 https://ai-ziyuan.techwisdom.cn/,你将进入一个全方位涵盖人工智能和语言模型领域的宝藏库。


作者:路条编程(转载请获本公众号授权,并注明作者与出处)
继续滑动看下一个
路条编程
向上滑动看下一个

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存