1 什么是热部署?
热部署,就是在应⽤正在运⾏的时候升级软件(增加业务/修改bug),却不需要重新启动应⽤。
⼤家都知道在项⽬开发过程中,常常会改动⻚⾯数据或者修改数据结构,为了显示改动效果,往往需 要重启应⽤查看改变效果,其实就是重新编译⽣成了新的 Class ⽂件,这个⽂件⾥记录着和代码等对应 的各种信息,然后 Class ⽂件将被虚拟机的 ClassLoader 加载。
⽽热部署正是利⽤了这个特点,它监听到如果有 Class ⽂件改动了,就会创建⼀个新的 ClaassLoader 进⾏加载该⽂件,经过⼀系列的过程,最终将结果呈现在我们眼前,Spring Boot 通过配 置 DevTools ⼯具来达到热部署效果。
在原理上是使⽤了两个 ClassLoader,⼀个 ClassLoader 加载那些不会改变的类(第三⽅ Jar 包), 另⼀个ClassLoader 加载会更改的类,称为 restart ClassLoader,这样在有代码更改的时候,原来的 restart ClassLoader 被丢弃,重新创建⼀个 restart ClassLoader,由于需要加载的类相⽐较少,所以 实现了较快的重启时间。
2 热部署环境配置与测试
2.1 配置 DevTools 环境
修改 Pom ⽂件,添加 DevTools 依赖:
<!-- DevTools 的坐标 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<!--当前这个项⽬被继承之后,这个不向下传递-->
<optional>true</optional>
</dependency>
同时在 plugin 中添加 devtools ⽣效标志:
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<fork>true</fork><!-- 如果没有该配置,热部署的devtools不⽣效 -->
</configuration>
</plugin>
devtools 可以实现⻚⾯热部署(即⻚⾯修改后会⽴即⽣效,这个可以直接在 application. properties⽂件中配置 spring.thymeleaf.cache=false 来实现),实现类⽂件热部署(类⽂件修改后不会⽴即⽣ 效),实现对属性⽂件的热部署。即 devtools 会监听 classpath 下的⽂件变动,并且会⽴即重启应⽤ (发⽣在保存时机),注意:因为其采⽤的虚拟机机制,该项重启是很快的。配置了后在修改 java ⽂ 件后也就⽀持了热启动,不过这种⽅式是属于项⽬重启(速度⽐较快的项⽬重启),会清空 session 中 的值,也就是如果有⽤户登陆的话,项⽬重启后需要重新登陆。
默认情况下,/META-INF/maven,/METAINF/resources,/resources,/static,/templates, /public 这些⽂件夹下的⽂件修改不会使应⽤重 启,但是会重新加载( devtools 内嵌了⼀个 LiveReload server,当资源发⽣改变时,浏览器刷新)
2.2 全局配置文件配置
在 application.yml 中配置 spring.devtools.restart.enabled=false,此时 restart 类加载器还会初始化,但不会监视⽂件更新。
spring:
## 热部署配置
devtools:
restart:
enabled: true
# 设置重启的⽬录,添加⽬录的⽂件需要restart
additional-paths: src/main/java
# 解决项⽬⾃动重新编译后接⼝报404的问题
poll-interval: 3000
quiet-period: 1000
2.3 IDEA配置
当我们修改了 Java 类后,IDEA 默认是不⾃动编译的,⽽ spring-boot-devtools ⼜是监测 classpath 下的⽂件发⽣变化才会重启应⽤,所以需要设置 IDEA 的⾃动编译。
⾃动编译配置:File -> Settings -> Compiler -> Build Project automatically
Registry 属性修改:ctrl + shift + alt + /,选择Registry,勾上 Compiler autoMake allow when app running
2.4 热部署效果测试
第⼀次访问 user/{userName} 接⼝:
@GetMapping("user/{userName}")
@ApiOperation(value = "根据⽤户名查询⽤户记录")
@ApiImplicitParam(name = "userName",value = "查询参数",required =
true,paramType = "path")
public User queryUserByUserName(@PathVariable String userName){
return userService.queryUserByUserName(userName);
}
修改接⼝代码:
控制台打印接收的 userName 参数,ctrl+f9 键重新编译,浏览器访问
@GetMapping("user/{userName}")
@ApiOperation(value = "根据⽤户名查询⽤户记录")
@ApiImplicitParam(name = "userName",value = "查询参数",required =
true,paramType = "path")
public User queryUserByUserName(@PathVariable String userName){
System.out.println("查询参数 --> userName:"+userName);
return userService.queryUserByUserName(userName);
}
本站资源均来自互联网,仅供研究学习,禁止违法使用和商用,产生法律纠纷本站概不负责!如果侵犯了您的权益请与我们联系!
转载请注明出处: 免费源码网-免费的源码资源网站 » Java程序设计:spring boot(9)——应用热部署
发表评论 取消回复