Spring Boot 2.0 热部署指南

时间:2022-04-20 12:44:08

Spring Boot 2.0 支持热部署,实现方法很简单

Spring Boot 2.0 有几种热重载的选项。 推荐的方法是使用spring-boot-devtools

因为它提供了额外的开发时间功能,例如支持快速应用程序重启和LiveReload以及合理的开发时配置(如模板缓存)。 Devtools通过监视类路径的变化来工作。 这意味着静态资源更改必须“建立”,以使更改生效。 默认情况下,当您保存更改时,这会在Eclipse中自动发生。 在IntelliJ IDEA中,Make Project命令触发必要的构建。 由于默认的重新启动排除,对静态资源的更改不会触发应用程序的重新启动。 但是,他们确实会触发实时重新加载。

1. 静态资源热部署

如果使用的  Thymeleaf  模板,那么请直接在application.properties中添加

spring.thymeleaf.cache=false

如果使用的 FreeMarker 模板,那么请直接在application.properties中添加

spring.freemarker.cache=false

如果使用的 Groovy 模板,那么请直接在application.properties 中添加

spring.groovy.template.cache=false

2. spring-boot-devtools java热部署配置

spring-boot-devtools模块包含对自动应用程序重新启动的支持。

虽然速度不如JRebel这样的技术,但它通常比“冷启动”快得多。

使用方式:

添加Maven依赖

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

添加Gradle依赖

dependencies {
compile("org.springframework.boot:spring-boot-devtools")
}

总结:

如果使用war方式部署的话,修改了java文件,那么必须重启tomcat.

如果使用jar方式部署,

  • Eclipse中保存即可热部署
  • Ideal Indea 需要rebuild project

最常用配置:

# 是否使用模板缓存
spring.thymeleaf.cache=false
#spring.freemarker.cache=false
#spring.groovy.template.cache=false
#如果不想使用重启功能,可以使用spring.devtools.restart.enabled属性来禁用它
spring.devtools.restart.enabled=true
#与LiveReload一起使用时,自动重启的效果非常好。
spring.devtools.livereload.enabled=true
#配置监视其他路径的更改
spring.devtools.restart.additional-paths=src/main/java
#仅排除/static你将设置以下内容:
spring.devtools.restart.exclude=static/**

3. spring-boot-devtools 热部署使用

3.1 properties 默认值

spring-boot-devtools模块会自动应用合理的开发时配置,不需要手动配置。

DevToolsPropertyDefaultsPostProcessor

    static {
Map<String, Object> devToolsProperties = new HashMap<>();
devToolsProperties.put("spring.thymeleaf.cache", "false");
devToolsProperties.put("spring.freemarker.cache", "false");
devToolsProperties.put("spring.groovy.template.cache", "false");
devToolsProperties.put("spring.mustache.cache", "false");
devToolsProperties.put("server.servlet.session.persistent", "true");
devToolsProperties.put("spring.h2.console.enabled", "true");
devToolsProperties.put("spring.resources.cache.period", "0");
devToolsProperties.put("spring.resources.chain.cache", "false");
devToolsProperties.put("spring.template.provider.cache", "false");
devToolsProperties.put("spring.mvc.log-resolved-exception", "true");
devToolsProperties.put("server.servlet.jsp.init-parameters.development", "true");
devToolsProperties.put("spring.reactor.stacktrace-mode.enabled", "true");
PROPERTIES = Collections.unmodifiableMap(devToolsProperties);
}

3.2 自动重启

每当类路径上的文件发生更改时,使用spring-boot-devtools的应用程序都会自动重新启动。在IDE中工作时,这可能是一个有用的功能,因为它为代码更改提供了非常快速的反馈循环。 默认情况下,监视指向文件夹的类路径中的任何条目以进行更改。 请注意,某些资源(如静态资产和视图模板)不需要重新启动应用程序。

默认仅排除/ static和/ public,您将设置以下属性:

spring.devtools.restart.exclude=static/**,public/**

Tips; 如果希望保留这些默认值并添加其他排除项,请改用spring.devtools.restart.additional-exclude属性

3.2.1 触发重启

由于DevTools监控类路径资源,触发重启的唯一方法是更新类路径。 导致类路径更新的方式取决于您使用的IDE。

在Eclipse中,保存修改后的文件会导致更新类路径并触发重新启动。

在IntelliJ IDEA中,构建项目(Build - > Build Project)具有相同的效果。

3.2.2 LiveReload 一起使用

与LiveReload一起使用时,自动重启的效果非常好。

如果使用JRebel,则禁用自动重新启动,以支持动态类重新加载。 其他devtools功能(例如LiveReload和属性覆盖)仍然可以使用。

在application.properties添加如下配置

spring.devtools.livereload.enabled=true
  • 一次只能运行一个LiveReload服务器。 在开始应用程序之前,请确保没有其他LiveReload服务器正在运行。 如果您从IDE启动多个应用程序,则只有第一个应用程序支持LiveReload。
  • DevTools依靠应用程序上下文的关闭挂钩在重新启动期间关闭它。 如果您禁用了关闭挂钩(SpringApplication.setRegisterShutdownHook(false)),它将无法正常工作。
  • 在决定类路径中的条目是否会在更改时触发重新启动时,DevTools会自动忽略名为spring-boot,spring-boot-devtools,spring-boot-autoconfigure,spring-boot-actuator和spring-boot-starter的项目。
  • DevTools需要自定义ApplicationContext使用的ResourceLoader。 如果你的应用程序已经提供了一个,它将被包装。 不支持直接覆盖ApplicationContext上的getResource方法。

重新启动vs重新加载

Spring Boot提供的重启技术通过使用两个类加载器来工作。 不会更改的类(例如,来自第三方jar的类)将加载到基类加载器中。 您正在开发的类会加载到重启类加载器中。 当应用程序重新启动时,重启类加载器被丢弃并创建一个新类。 这种方法意味着应用程序重新启动通常比“冷启动”快得多,因为基类加载器已经可用并且已被填充。

如果您发现重启对于您的应用程序来说不够快,或者遇到类加载问题,则可以考虑从ZeroTurnaround中重新加载技术,例如JRebel。 这些工作通过重写类,因为它们被加载,使它们更容易重新加载。

3.3 记录条件评估中的更改

默认情况下,每次应用程序重新启动时,都会记录显示条件评估增量的报告。 该报告显示了在您进行更改(如添加或删除Bean以及设置配置属性)时对应用程序自动配置的更改。

要禁用报告的日志记录,请设置以下属性:

spring.devtools.restart.log-condition-evaluation-delta=false

3.4 排除资源

某些资源不一定需要在更改时触发重新启动。 例如,可以就地编辑Thymeleaf模板。 默认情况下,更改/ META-INF / maven,/ META-INF / resources,/ resources,/ static,/ public或/ templates中的资源不会触发重新启动,但会触发实时重新加载。 如果你想自定义这些排除,你可以使用spring.devtools.restart.exclude属性。 例如,要仅排除/ static和/ public,您将设置以下属性:

spring.devtools.restart.exclude=static/**,public/**

Tips: 如果要保留这些默认值并添加其他排除项,请改为使用spring.devtools.restart.additional-exclude属性。

3.5 看额外的路径

您可能希望在更改不在类路径中的文件时重新启动或重新加载应用程序。 为此,请使用spring.devtools.restart.additional-paths属性来配置其他路径以监视更改。 您可以使用前面介绍的spring.devtools.restart.exclude属性来控制其他路径下的更改是触发完全重新启动还是实时重新加载。

#配置监视其他路径的更改
spring.devtools.restart.additional-paths=src/main/java

3.6 禁用重新启动

如果您不想使用重新启动功能,则可以使用spring.devtools.restart.enabled属性将其禁用。

在大多数情况下,您可以在application.properties中设置此属性(这样做仍会初始化重新启动类加载器,但它不会监视文件更改)。

如果需要完全禁用重新启动支持(例如,因为它不适用于特定库),则在调用SpringApplication.run(...)之前,需要将spring.devtools.restart.enabled System属性设置为false,如 如下例所示:

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

3.7 使用触发文件

如果您使用持续编译更改文件的IDE,则可能只希望在特定时间触发重新启动。 为此,您可以使用“触发文件”,这是一个特殊文件,当您想要实际触发重新启动检查时必须对其进行修改。 只更改文件会触发检查,只有在Devtools检测到必须执行某些操作时才会重新启动。 触发文件可以手动更新或使用IDE插件更新。

要使用触发器文件,请将spring.devtools.restart.trigger-file属性设置为触发器文件的路径

您可以通过将名为.spring-boot-devtools.properties的文件添加到您的$ HOME文件夹来配置全局devtools设置(请注意文件名以“。”开头)。 添加到此文件的任何属性都适用于使用devtools的计算机上的所有Spring Boot应用程序。 例如,要将重新启动配置为始终使用触发器文件,您可以添加以下属性:

~/.spring-boot-devtools.properties.

spring.devtools.reload.trigger-file=.reloadtrigger

您可能需要将spring.devtools.restart.trigger-file设置为全局设置,以便所有项目的行为方式相同。

3.8 自定义重启类加载器

如前面的“重新启动vs重新加载”部分所述,重新启动功能通过使用两个类加载器来实现。 对于大多数应用程序,这种方法运作良好 但是,它有时会导致类加载问题。

默认情况下,IDE中任何打开的项目都会加载“restart”类加载器,并且任何常规的.jar文件都会加载“base”类加载器。 如果您使用多模块项目,并且不是每个模块都导入到IDE中,则可能需要自定义。 为此,您可以创建一个META-INF / spring-devtools.properties文件。

spring-devtools.properties文件可以包含以restart.exclude和restart.include为前缀的属性。 include元素是应该被拉入到“重启”类加载器中的项目,而排除元素是应该被下推到“基本”类加载器中的项目。 该属性的值是应用于类路径的正则表达式模式,如以下示例所示:

restart.exclude.companycommonlibs=/mycorp-common-[\\w-]+\.jar
restart.include.projectcommon=/mycorp-myproj-[\\w-]+\.jar

所有属性键必须是唯一的。 只要属性以restart.include开头。 或重新启动。排除。 已经被考虑了。

加载类路径中的所有META-INF / spring-devtools.properties。 您可以将文件打包到您的项目中,也可以打包到项目使用的库中。

3.9  著名的限制

对于使用标准ObjectInputStream进行反序列化的对象,重新启动功能无法正常工作。

如果你需要反序列化数据,你可能需要结合使用Spring的ConfigurableObjectInputStream和Thread.currentThread()。getContextClassLoader()。

不幸的是,有些第三方库反序列化而没有考虑上下文类加载器。 如果您发现这样的问题,您需要向原作者请求修复。