1.介绍

在开发工程中,修改一点儿代码,想看效果就需要重新启动服务,这样会花费大量时间在重启服务上,通过devtools热部署可以大大减少重启服务的时间。

之所以能减少时间,是因为Spring Boot自动重启的原理在于使用两个classloader:不改变的类(如第三方jar)由base类加载器加载,正在开发的类由restart类加载器加载。应用重启时,restart类加载器被扔掉重建,而base类加载器不变,这种方法意味着应用程序重新启动通常比“冷启动”快得多,因为base类加载器已经可用并已填充。

注意:不同的IDE效果不一样,Eclipse中保存文件即可引起classpath更新(需要打开自动编译),从而触发重启。而IDEA则需要自己手动command+F9(Mac OS X 10.5+版本的快捷键,其他版本的可能有所不同,根据自己的情况而定)重新编译一下

 

spring为开发者提供了一个名为spring-boot-devtools的模块来使Spring Boot应用支持热部署,提高开发者的开发效率,无需手动重启Spring Boot应用。

devtools的原理

深层原理是使用了两个ClassLoader,一个Classloader加载那些不会改变的类(第三方Jar包),另一个ClassLoader加载会更改的类,称为restart ClassLoader,这样在有代码更改的时候,原来的restart ClassLoader 被丢弃,重新创建一个restart ClassLoader,由于需要加载的类相比较少,所以实现了较快的重启时间。

这里我没有把所有的方式都尝试一遍,只是使用了devtools的方式

总的来说,一共需要两个步骤:

第一步、先设置我们的pom.xml文件,加入依赖

首先是把下面代码在<dependencies>中

  1.  
    <!--添加热部署-->
  2.  
    <dependency>
  3.  
    <groupId>org.springframework.boot</groupId>
  4.  
    <artifactId>spring-boot-devtools</artifactId>
  5.  
    <optional>true</optional>
  6.  
    <scope>true</scope>
  7.  
    </dependency>

另外下面的代码是放在<build>  下面<plugins>里的

  1.  
    <plugin>
  2.  
    <!--热部署配置-->
  3.  
    <groupId>org.springframework.boot</groupId>
  4.  
    <artifactId>spring-boot-maven-plugin</artifactId>
  5.  
    <configuration>
  6.  
    <!--fork:如果没有该项配置,整个devtools不会起作用-->
  7.  
    <fork>true</fork>
  8.  
    </configuration>
  9.  
    </plugin>

第二步、设置IDEA的自动编译:

(1)File-Settings-Compiler勾选 Build Project automatically

(2)快捷键 ctrl + shift + alt + /,选择Registry,勾上 Compiler autoMake allow when app running

这样我们的热部署就完成了,可以再我们的项目中修改返回值,或者修改Mapping的value值后,在我们的页面中刷新试试,

我们的修改已经生效了,不用通过再关闭再开启项目查看了。

 

例子:

 

pom.xml文件:

<!-- Spring Boot启动器父类 -->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.1.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>

<dependencies>
<!-- Spring Boot web启动器 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional> <!-- 防止将devtools依赖传递到其他模块中 -->
</dependency>
</dependencies>
启动类Application:

package com.songguoliang.springboot;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

/**
* @Description
* @Author sgl
* @Date 2018-05-02 14:51
*/
@SpringBootApplication
public class Application{
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}


}


添加依赖
集成devtools只需要添加下面的依赖即可,通过<optional>true</optional>可防止依赖传递。

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional> <!-- 防止将devtools依赖传递到其他模块中 -->
</dependency>


测试
我们先启动服务,然后再创建HelloController,代码如下:

package com.songguoliang.springboot.controller;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

/**
* @Description
* @Author sgl
* @Date 2018-05-09 10:21
*/
@RestController
public class HelloController {
@GetMapping("/hello")
public String hello(){
return "hello";
}

}

此时我们无需重启服务,便可以访问http://localhost:8080/hello,(注:eclipse需开启自动编译,idea需要重新编译)