开发的过程中,我们常常被一些无关紧要的事情浪费时间,我个人认为重启服务就是最大坑,因为现在维护公司的一个系统是12年前的项目,结构比较复杂,而且代码臃肿。开发过程中便宜与启动Tomcat基本就半小时过去了,junit也是。所以在后续项目开发与学习过程中,都在找热部署发布的功能,不再因为一行代码或者一行日志而重新便宜,重启服务。
sprinigboot的热部署有两种方式:
1. 通过springloader进行热部署
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin </artifactId>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>springloaded</artifactId>
<version>1.2.4.RELEASE</version>
</dependency>
</dependencies>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
<configuration>
<classifier>exec</classifier>
</configuration>
</execution>
</executions>
</plugin>
添加springloader只需要在pom文件中加入如上插件就行,然后通过maven command模式启动。也可以在ide中使用run as javaApplication启动,使用该种模式启动时需要进行一些配置:
- 下载springloaded-1.2.4.RELEASE.jar到指定文件夹
- 添加运行命令:-javaagent:.\lib\springloaded-1.2.4.RELEASE.jar -noverify(具体添加方式根据ide的不同自行设定)
2. 通过springboot提供的开发者模块:devtools
.....
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
<scope>true</scope>
</dependency>
.....
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<!--fork : 如果没有该项配置,肯呢个devtools不会起作用,即应用不会restart -->
<fork>true</fork>
</configuration>
</plugin>
相比与springloader,devtools在pom文件中首先要引入依赖,其次是添加devtools的编译插件。这两步实现后,不需要设置其他内容,可直接启动
devtools实现原理
devtools使用了两个ClassLoader,一个Classloader加载那些不会改变的类(第三方Jar包),另一个ClassLoader加载会更改的类,称为 restart ClassLoader
,这样在有代码更改的时候,原来的restart ClassLoader 被丢弃,重新创建一个restart ClassLoader,由于需要加载的类相比较少,所以实现了较快的重启时间(5秒以内)。
两种方式对比
- springloader热部署只可以修改已有方法与页面,如果是新加的方法或者类无法自动部署。而devtools监控的是classpath下所有文件变更,如果发生变更则自动部署。包括配置文件、类、页面等
- devtools可以实现页面热部署(即页面修改后会立即生效,这个可以直接在application.properties文件中配置spring.thymeleaf.cache=false来实现(这里注意不同的模板配置不一样)。网络资料,没有亲测。
- springloader如果是普通启动,需要下载jar包,并且配置相关启动参数
devtools开发注意事项:
- 选择对应的spring-boot版本,添加依赖时尽量不要自己设置版本号,springboot会选择合适的版本
- pom中加入plugin以及属性true
- 确定IDE是否开启自动编译,我自己使用idea,自动编译是关着的,需要部署,Ctrl + F9
- 如果设置SpringApplication.setRegisterShutdownHook(false),则自动重启将不起作用。