83. Hot swapping

83.1 重新加载静态内容

有几种热重装选项。推荐的方法是使用spring-boot-devtools,因为它提供了其他开发时功能,例如对应用程序快速重启和 LiveReload 的支持以及合理的开发时配置(例如模板缓存)。 Devtools 通过监视 Classpath 的更改来工作。这意味着必须“构建”静态资源更改才能使更改生效。默认情况下,当您保存更改时,这会自动在 Eclipse 中发生。在 IntelliJ IDEA 中,Make Project 将触发必要的构建。由于默认重启排除,更改静态资源不会触发您的应用程序重新启动。但是,它们将触发实时重新加载。

另外,在 IDE 中运行(特别是在调试时打开)是进行开发的好方法(所有现代 IDE 都允许重新加载静态资源,并且通常还可以热交换 Java 类更改)。

最后,可以配置Maven 和 Gradle 插件(请参见addResources属性)以支持从命令行运行,并直接从源中重新加载静态文件。如果您正在使用高级工具编写该代码,则可以将其与外部 css/js 编译器进程一起使用。

83.2 无需重新启动容器即可重新加载模板

Spring Boot 支持的大多数模板技术都包含用于禁用缓存的配置选项(有关详细信息,请参见下文)。如果您使用的是spring-boot-devtools模块,那么在开发时这些属性将为automatically configured

83.2.1Thymeleaf 模板

如果您正在使用 Thymeleaf,则将spring.thymeleaf.cache设置为false。有关其他 Thymeleaf 定制选项,请参见ThymeleafAutoConfiguration

83.2.2 FreeMarker 模板

如果您使用的是 FreeMarker,则将spring.freemarker.cache设置为false。有关其他 FreeMarker 自定义选项,请参见FreeMarkerAutoConfiguration

83.2.3 Groovy 模板

如果使用的是 Groovy 模板,则将spring.groovy.template.cache设置为false。有关其他 Groovy 定制选项,请参见GroovyTemplateAutoConfiguration

83.3 快速应用程序重新启动

spring-boot-devtools模块包括对应用程序自动重启的支持。尽管不如JRebelSpring Loaded等技术快,但通常比“冷启动”要快得多。在研究下面讨论的一些更复杂的重载选项之前,您可能应该尝试一下。

有关更多详细信息,请参见第 20 章,开发人员工具部分。

83.4 无需重新启动容器即可重新加载 Java 类

现代的 IDE(Eclipse,IDEA 等)均支持字节码的热交换,因此,如果所做的更改不影响类或方法签名,则应干净地重新加载而没有副作用。

Spring Loaded更进一步,它可以通过更改方法签名来重新加载类定义。通过一些自定义,它可以强制ApplicationContext刷新自身(但是没有通用机制可以确保无论如何对于正在运行的应用程序来说都是安全的,因此这可能只是开发时间的窍门)。

83.4.1 配置 Spring Loaded 以与 Maven 一起使用

要通过 Maven 命令行使用 Spring Loaded,只需将其作为依赖项添加到 Spring Boot 插件声明中即可,例如

<plugin>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-maven-plugin</artifactId>
    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>springloaded</artifactId>
            <version>1.2.6.RELEASE</version>
        </dependency>
    </dependencies>
</plugin>

只要 Eclipse 和 IntelliJ IDEA 的构建配置与 Maven 的默认值保持一致(Eclipse m2e 开箱即用),这通常就可以很好地工作。

83.4.2 配置 Spring Loaded 以与 Gradle 和 IntelliJ IDEA 一起使用

如果要将 Spring Loaded 与 Gradle 和 IntelliJ IDEA 结合使用,则需要跳过几个步骤。默认情况下,IntelliJ IDEA 会将类编译到与 Gradle 不同的位置,从而导致 Spring Loaded 监视失败。

要正确配置 IntelliJ IDEA,可以使用idea Gradle 插件:

buildscript {
    repositories { jcenter() }
    dependencies {
        classpath "org.springframework.boot:spring-boot-gradle-plugin:1.5.9.RELEASE"
        classpath 'org.springframework:springloaded:1.2.6.RELEASE'
    }
}

apply plugin: 'idea'

idea {
    module {
        inheritOutputDirs = false
        outputDir = file("$buildDir/classes/main/")
    }
}

// ...

Note

必须将 IntelliJ IDEA 配置为使用与命令行 Gradle 任务相同的 Java 版本,并且必须包含springloaded **作为buildscript依赖项。

您还可以在 IntelliJ IDEA 中启用“自动创建项目”,以便在保存文件时自动编译代码。