SpringBoot系列教程13--SpringBoot开发利刃之热部署原理及最优实践
作者:一一哥
一.SpringBoot的热部署
1.概述
Spring Boot为开发者提供了一个名为spring-boot-devtools的额外工具模块来使得Spring Boot应用支持热部署,提高开发者的开发效率,无需手动重启Spring Boot应用,以此提升了Spring Boot应用的开发体验。
spring-boot-devtools模块可以被引入到任何模块中,以提供development-time特性。
2.自动重启
如果项目中使用了spring-boot-devtools插件,只要classpath下的java文件有了变动,我们的项目就会自动重启。这样我们就可以很快就能看到代码改变后的效果了。
默认情况下,classpath下任何指向文件夹的实体类都会被监控,但是一些资源的修改,尤其是静态的assets,视图模板不会触发重启应用。具体的,比如更改/META-INF/maven,/META-INF/resources ,/resources ,/static ,/public 或/templates下的资源不会触发重启,而是触发livereload。
排除资源
我们可以使用spring.devtools.restart.exclude属性自定义这些重启的排除规则,比如,为了只排除/static和/public,你可以这样设置:
注意:
如果你想保留默认属性,并添加其他的排除规则,可以使用spring.devtools.restart.additional-exclude属性作为代替。
3.livereload简介
在devtools模块中包含一个嵌入的livereload服务器,可以在资源变化时用来触发浏览器刷新。
livereload 通过引入的脚本livereload.js在 livereload 服务和浏览器之间建立了一个 WebSocket 连接。每当监测到文件的变动,livereload 服务就会向浏览器发送一个信号,浏览器收到信号后就刷新页面,实现了实时刷新的效果。每次启动时,需要点击对应的图标,如下图所示。
我们的浏览器需要在http://livereload.com网站下载安装扩展插件。Chrome浏览器在应用商店安装livereload插件后,在要自动刷新的页面点击对应的图标,启动应用后更新页面内容或者css等都会触发页面自动刷新。
4.触发重启的条件
由于DevTools监控的是classpath下的资源,所以唯一触发重启的条件就是更新classpath。引起classpath更新的方式依赖于你使用的IDE工具,在Eclipse里,保存一个修改的文件将引起classpath更新,并触发重启。在IntelliJ IDEA中,构建工程(Build → Make Project)也会达到同样的效果。
当判定classpath下实体的改变是否会触发重启时,DevTools自动忽略以下工程:spring-boot,spring-boot-devtools,spring-boot-autoconfigure,spring-boot-actuator和spring-boot-starter。
注意:
你也可以通过支持的构建工具(比如,Maven和Gradle)来启动应用,只要开启fork功能,因为DevTools需要一个隔离的应用类加载器执行正确的操作。Gradle默认支持该行为,按照以下配置可强制Maven插件fork进程:
Restart vs Reload的原理及区别
Spring Boot提供的重启技术是通过使用两个类加载器实现的。没有发生变化的类(比如那些第三方jars)会被加载进一个基础(basic)classloader里面,正在开发的类会加载进一个重启(restart)classloader里面。当应用重启时,restart类加载器会被丢弃,并创建一个新的。这种方式意味着应用重启通常比冷启动(cold starts)快很多,因为基础类加载器已经可用,并且populated(意思是基础类加载器加载的类比较多)。
如果发现重启对于你的应用来说不够快,或遇到类加载的问题,那可以考虑reload技术,比如JRebel,这些技术是通过重写它们加载过的类来实现的。Spring Loaded提供了另一种实现方案,然而很多框架都不支持它,也得不到商业支持。
二.最佳实践
上面给大家普及了Spring Boot热部署的触发条件和实现机制,接下来还是来点干活,说一下在代码中到底该怎么配置,我们来具体实践一下。
1.项目代码配置
1.1.pom.xml配置文件
1.2.yml配置
2.IDEA配置
2.1.File-Settings-Compiler-Build project automatically
2.2.ctrl + shift + alt + /,选择Registry,勾上 Compiler autoMake allow when app running
3.安装livereload插件
下载livereload插件,将其安装到chrome扩展程序中,并选中允许访问文件网址。
4.测试
一开始我们的代码如下:
4.1 修改类
随便修改一个java代码类,应用就会自动重启。
4.2 修改配置文件
应用会重启。
4.3 修改静态文件(html、css等)
应用不会重启,但是会调用livereload,浏览器会自动刷新,显示最新的修改内容。
5.禁用重启
如果我们不想使用重启特性,可以通过‘spring.devtools.restart.enabled’属性来禁用它。通常情况下可以在application.properties文件中设置(依旧会初始化重启类加载器,但它不会监控文件变化)。
如果需要彻底禁用重启支持,比如,不能跟某个特殊库一块工作,你需要在调用SpringApplication.run(…)之前设置一个系统属性,如下: