在 Spring Boot 2.1 中热重载 Thymeleaf 模板和资源包

Posted

技术标签:

【中文标题】在 Spring Boot 2.1 中热重载 Thymeleaf 模板和资源包【英文标题】:Hot Reloading Thymeleaf Templates and Resource Bundles in Spring Boot 2.1 【发布时间】:2019-07-17 14:33:45 【问题描述】:

我创建了一个启用 i18n 的 Spring Boot 2.1.3 应用程序,添加了开发工具,并安装了 Firefox LiveReload 扩展。不幸的是,当我更改我的 Thymeleaf 模板或 i18n 消息时,它并没有改变。 Spring Boot documentation 似乎暗示您需要做的就是安装 devtools,它会禁用静态资源的缓存。

这是我创建应用程序时所做的:

mkdir bootiful-i18n
cd bootiful-i18n
http https://start.spring.io/starter.zip dependencies==web,thymeleaf -d | tar xvz

然后我创建了一个HomeController.java

package com.example.demo;

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

@Controller
public class HomeController 

   @GetMapping("/")
   String home() 
       return "home";
   

我在src/main/resources/templates/home.html 创建了一个 Thymeleaf 模板:

<html xmlns:th="http://www.thymeleaf.org">
<body>
   <h1 th:text="#title"></h1>
   <p th:text="#message"></p>
</body>
</html>

我在src/main/resources 中添加了一个messages.properties 文件:

title=Welcome
message=Hello! I hope you're having a great day.

这一切都很好。为了启用热重载,我将 devtools 添加到 pom.xml

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-devtools</artifactId>
</dependency>

并安装了LiveReload extension for Firefox。

我重新启动服务器,启用 LiveReload 并导航到 http://localhost:8080。我尝试更改并保存home.htmlmessages.properties 并刷新我的浏览器。浏览器中的输出不会改变。我还需要做些什么来禁用 Spring Boot 2.1 中 Thymeleaf 模板和消息包的缓存吗?

【问题讨论】:

【参考方案1】:

Devtools 将禁用缓存,以便在需要再次渲染模板文件时重新考虑更新。

当您的应用程序在 JVM 进程中启动时,没有任何东西指向您的源文件,它只能看到类路径。因此,您对源文件所做的任何更改都需要更新到类路径位置,这通常通过要求您的 IDE“构建项目”来实现。

因此,模板缺少的步骤是,如果文档对此不清楚,请随时提出建议,因为我们已经对此进行了很多迭代。

但 i18n 并没有什么特别之处。如果您更改它们并更新类路径,我们将重新启动应用程序,而不是像我们为模板所做的那样选择它。我们曾经尝试过支持这一点,请参阅this issue for more details。话虽如此,您不应该期望对资源文件的更改“会起作用”。例如,对配置的更改显然需要重新启动应用程序(同样,通过在使用 devtools 时更新类路径)。

一些关于 IDE 支持的补充说明:

Eclipse 在“保存”时增量编译和复制更改的文件。所以如果你保存你的模板,你应该很高兴 IntelliJ IDEA Ultimate 自 2018.1 起具有 dedicated devtools support - 如果您将“帧停用”配置为“更新资源”,它会在您切换到浏览器时执行正确的操作。在此支持之前,我有一个特殊的按键映射到“构建项目”(增量编译和复制资源),每当我希望我的更改得到反映时,我都会调用它

如果您不使用 IDE,则需要为您更新类路径。我们已经尝试支持开箱即用,但结果证明非常复杂。有a comment to help you if you're using Gradle。

【讨论】:

感谢斯蒂芬妮的建议。我发现 spring.thymeleaf.cachespring.thymeleaf.prefix 都是热重载 Thymeleaf 模板所必需的。对于 i18n,构建或“帧停用更新”(两者都会导致应用重新加载)有效。谢谢! 更正,spring.thymeleaf.prefix 如果您想在不使用 IDE 和 vi 之类的东西时进行热重载,则需要。 spring.thymeleaf.cache 似乎没有必要。【参考方案2】:

将以下内容添加到您的application.properties

spring.thymeleaf.cache=false

【讨论】:

我最近新建了一个项目,父项:spring-boot-starter-parent,依赖项:spring-boot-starter-tomcat,spring-boot-starter-thymeleaf,我编辑时刷新模板他们。虽然我没有尝试过属性。 我必须同时添加 spring.thymeleaf.cachespring.thymeleaf.prefix 才能使热重载工作。 FWIW,当我第一次尝试让事情正常工作时,我正在使用 Vi。也许您正在使用 Eclipse 或在您更改文件时自动更新目标目录的东西?

以上是关于在 Spring Boot 2.1 中热重载 Thymeleaf 模板和资源包的主要内容,如果未能解决你的问题,请参考以下文章

spring-boot-devtools在Idea中热部署方法

spring-boot-devtools在Idea中热部署方法

如何在 ReactJS Docker 中热重载

如何在 NestJS 中热重载联邦网关

有没有办法在 Ktor 中热重载静态文件?

使用 golang 在 docker 中热重载不起作用(github.com/cosmtrek/air)