spring为开发者提供了一个名为spring-boot-devtools的模块来使Spring Boot应用支持热部署,提高开发者的开发效率,无需手动重启Spring Boot应用。
在项目中添加 spring-boot-devtools
非常简单,只需要添加以下依赖项即可:
maven
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
因为 spring-boot-devtools
一般只使用于开发环境,在生产环境是需要禁用的,所以得设置 optional=true
(maven) 或是 developmentOnly
(gradle),这样一来,当我们在生产环境启动服务时(比如通过 java -jar
方式启动),spring-boot-devtools
会被禁用。同时,Repackaged
生成的包默认情况下也是不包含 devtools
的,如有需要,可以通过设置 excludeDevtools
为 false
来启用它。
Dev Tools 的特性
默认属性
Spring Boot
为了支持某些库使用缓存来提高性能,提供了一些设置,如:spring.thymeleaf.cache
,它将会缓存编译模板,避免因模板的重复解析而降低系统性能,这在生产环境中是非常重要的,但是在本地开发时,这会导致我们每次修改模板都要重启服务,大大降低了开发速度,为了避免这个问题,我们需要手动禁用 thymeleaf
缓存,但是如果你的项目中添加了 devtools
,那我们就不需要去一一设置这些选项了,devtools
为此提供了非常多的默认设置。
devtools
提供的所有默认选项请参考:DevToolsPropertyDefaultsPostProcessor
如果你需要禁用
devtools
提供的默认属性,请设置spring.devtools.add-properties=false
自动重启服务
当项目 classpath
下的文件发生了变动,devtools
将会帮我们自动重启服务,这也是个非常有用的功能。
触发重启
因为 devtools
将会监控应用的 classpath
下的资源,因此当 classpath
下的资源发生了变更时,应用就会被重启。在 Eclipse
中,保存修改后的文件将会触发重启;在 Idea
中,构建项目(Build -> Build Project
)将会导致应用重启。
但是有几点需要注意:
-
devtools
将会使用独立的类加载器。 -
devtools
依赖应用程序关闭钩子,如果你的应用禁用了关闭钩子(SpringApplication.setRegisterShutdownHook(false)
),devtools
将会失效。 - 在决定是否应该触发重启时,
devtools
将会自动忽略名为spring-boot
,spring-boot-devtools
,spring-boot-autoconfigure
,spring-boot-actuator
和spring-boot-starter
的项目。
重启 vs 重新加载
Spring Boot
的重启和我们手动的重启有一些区别,因为 Spring Boot
将会使用两个类加载器来加载我们的应用,其中一个用于加载不会变更的类(如:第三方 jar) ,另外一个则用于加载我们开发的程序,在应用重新启动时,基本类加载器不会变,但是 Spring Boot
将会直接丢弃用于加载我们自己程序的类加载器,并重新创建一个类加载器加载变更后的应用,因为这样,这种方式启动应用将比普通方式启动更快,因为基础类已经被加载。
如果你觉得 Spring Boot
提供的重启还是不够快的话,可以尝试使用其它的基于 Reload
的技术,如 JRebel
。
条件评估结果日志
在默认情况下,每次重启时,Spring Boot
将会记录条件评估的结果报告。这个报告将会展示你的应用
auto-configuration
的变更(如增加或删除 Bean
以及配置属性的变更)。你也可以通过以下属性禁用它:
spring.devtools.restart.log-condition-evaluation-delta=false
排除不需要触发重启的资源
我们的应用中,某些资源的修改其实不需要重启服务,比如前端使用的静态资源文件,默认情况下,Spring Boot
在以下这些目录中的资源变更时,不会触发重启(但是会触发 live reload):
/META-INF/maven , /META-INF/resources , /resources , /static , /public , /templates
我们也可以手动指定这些路径:
spring.devtools.restart.exclude=static/**,public/**
如果你只是项额外增加路径而不覆盖 Spring Boot
提供的默认设置时,你可以设置这个属性:
spring.devtools.restart.additional-exclude = /custom-path/**
当你想设置的触发重启的文件不在 classpath
下的时候,你还可以使用以下设置作为触发应用重启的条件:
spring.devtools.restart.additional-paths
禁用自动重启
如果你不想使用 devtools
提供的自动重启功能,你也可以设置 spring.devtools.restart.enabled
属性来禁用它。
指定特殊文件触发重启
你可以通过设置 spring.devtools.restart.trigger-file
属性来指定触发重启的文件(常用于 IDE 持续的自动编译 class 导致应用一直重启)。
自定义重启使用的类加载器
在上面我们说过 devtools
将会使用两个类加载器用于重启应用,我们可以通过以下属性指定 classpath
下面的某个包使用哪个类加载器:
restart.exclude.companycommonlibs=/mycorp-common-[\\w-]+\.jar
restart.include.projectcommon=/mycorp-myproj-[\\w-]+\.jar
注:以上的属性需要添加到
classpath: META-INF/spring-devtools.properties
路径下。
LiveReload
devtools
包含了内置的服务器用于 live reload ,你可以通过属性 spring.devtools.livereload.enabled
来禁它。
全局设置
你可以在本地目录 ($HOME/.spring-boot-devtools.properties
) 添加 devtools
的全局配置文件 (.spring-boot-devtools.properties
)来设置 devtools
。如:
windows
C:\Users\当前用户\.spring-boot-devtools.properties