使用spring-boot-devtools热部署项目

IDEA新建一个Maven项目

pom.xml中加入spring-boot-devtools依赖

<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-devtools -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <optional>true</optional>
            <scope>true</scope>
        </dependency>
复制代码

注意,还需要加入spring-boot-maven-plugin

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <!--如果没有该配置,devtools不会起作用,即应用不会restart-->
                    <fork>true</fork>
                </configuration>
            </plugin>
        </plugins>
    </build>
复制代码

创建启动类和控制器类、页面

package com.example.demo;

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

@SpringBootApplication
public class SpringBootDemoApplication {
    public static void main(String[] args) {
        SpringApplication.run(SpringBootDemoApplication.class, args);
    }
}
复制代码
package com.example.demo.controller;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
@RequestMapping("hello")
public class HelloController {

    @RequestMapping("index")
    public String index(Model model){

        model.addAttribute("who","spring boot");
        return "hello/index.html";
    }
}
复制代码
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="utf-8">
    <title>spring boot demo</title>
</head>
<body>
    <p th:text="${who}"></p>
</body>
</html>
复制代码

页面热部署需要在application.yml中配置

复制代码
spring:
  thymeleaf:
    cache: false
复制代码

代码修改后不能热部署

原因:

Spring Boot Devtools会监控类路径目录,如果类路径下的文件发生了变化(比如重新编译),则Spring Boot Devtools会重新加载和重启Spring Boot应用。

而在Intellij中,默认不会自动编译(auto build),并且默认不会更新正在运行的应用。

这就导致了在Intellj中修改代码后,Spring Boot应用不会重新加载新的类文件。

方法:

手动触发构建,修改代码后,选择 Build / Build project (Win/Linux: CTRL + F9, Mac: COMMAND + F9)

项目简介

平时使用SpringBoot开发应用时,修改代码后需要重新启动才能生效。如果你的应用足够大的话,启动可能需要好几分钟。有没有什么办法可以加速启动过程,让我们开发应用代码更高效呢?今天给大家推荐一款SpringBoot官方的热部署工具spring-boot-devtools,修改完代码后可快速自动重启应用!

spring-boot-devtools简介

SpringBoot官方开发工具,如果你的应用集成了它,即可实现热部署和远程调试。

实现原理

使用该工具应用为什么启动更快了?主要是因为它使用了两种不同的类加载器。基础类加载器用于加载不会改变的类(比如第三方库中的类),重启类加载器用于加载你应用程序中的类。当应用程序启动时,重启类加载器中的类将会被替换掉,这就意味着重启将比冷启动更快!

热部署

接下来我们将集成devtools,来演示下热部署功能。

  • 首先需要在项目的pom.xml文件中,添加devtools的依赖;
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-devtools</artifactId>
    <optional>true</optional>
</dependency>
复制代码
  • 为了方便测试,我们在项目中添加了如下测试接口;
/**
 * Created by macro on 2021/3/25.
 */
@Api(tags = "TestController", description = "SpringBoot Dev Tools测试")
@Controller
@RequestMapping("/test")
public class TestController {

    @ApiOperation("测试修改")
    @RequestMapping(value = "/first", method = RequestMethod.GET)
    @ResponseBody
    public CommonResult first() {
        String message = "返回消息";
        return CommonResult.success(null,message);
    }
}
复制代码
{
  "code": 200,
  "message": "返回消息",
  "data": null
}
复制代码
  • 由于在项目构建时,devtools才会自动重启项目,而IDEA默认并没有使用自动构建,此时我们可以修改应用启动配置,设置当IDEA失去焦点时自动构建项目;

  • 修改Controller中的代码,只要修改下message变量即可;
/**
 * Created by macro on 2021/3/25.
 */
@Api(tags = "TestController", description = "SpringBoot Dev Tools测试")
@Controller
@RequestMapping("/test")
public class TestController {

    @ApiOperation("测试修改")
    @RequestMapping(value = "/first", method = RequestMethod.GET)
    @ResponseBody
    public CommonResult first() {
        String message = "返回消息(已修改)";
        return CommonResult.success(null,message);
    }
}
复制代码
  • 失去焦点后,等待项目自动构建,此时访问接口出现404问题;
{
  "timestamp": "2021-03-29T07:09:05.415+00:00",
  "status": 404,
  "error": "Not Found",
  "message": "No message available",
  "path": "/test/first"
}
复制代码
  • 由于devtools检测时间和IDEA的编译所需时间存在差异,当IDEA还没编译完成,devtools就已经重启应用了,导致了这个问题,修改application.yml配置文件,添加如下配置即可;
spring:
  devtools:
    restart:
      poll-interval: 2s
      quiet-period: 1s
复制代码
  • 此时再次访问测试接口,显示内容如下,修改后的代码已经被自动应用了。
{
  "code": 200,
  "message": "返回消息(已修改)",
  "data": null
}
复制代码

远程调试

devtools除了支持热部署之外,还支持远程调试,接下来我们把应用部署到Docker容器中,然后试试远程调试!

  • 由于SpringBoot默认打包不会包含devtools,所以我们需要先修改下pom.xml
<plugin>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-maven-plugin</artifactId>
    <configuration>
        <!--打包时不排除Devtools-->
        <excludeDevtools>false</excludeDevtools>
    </configuration>
</plugin>
复制代码
  • 接下来需要application.yml文件,添加devtools的远程访问密码;
spring:
  devtools:
    remote:
      secret: macro666
复制代码
  • 接下来把项目打包成Docker镜像,然后使用如下命令运行起来;
docker run -p 8088:8088 --name mall-tiny-devtools \
--link mysql:db \
-v /etc/localtime:/etc/localtime \
-v /mydata/app/mall-tiny/logs:/var/logs \
-d mall-tiny/mall-tiny-devtools:1.0-SNAPSHOT
复制代码
  • 添加一个启动配置,修改启动类为org.springframework.boot.devtools.RemoteSpringApplication,配置信息具体如下;

  • 启动该配置,控制台输出如下结果表示远程连接成功;
2021-03-29 15:49:50.991  INFO 7848 --- [           main] o.s.b.devtools.RemoteSpringApplication   : Starting RemoteSpringApplication v2.3.0.RELEASE on DESKTOP-5NIMJ19 with PID 7848
2021-03-29 15:49:51.003  INFO 7848 --- [           main] o.s.b.devtools.RemoteSpringApplication   : No active profile set, falling back to default profiles: default
2021-03-29 15:49:51.664  WARN 7848 --- [           main] o.s.b.d.r.c.RemoteClientConfiguration    : The connection to http://192.168.5.78:8088 is insecure. You should use a URL starting with 'https://'.
2021-03-29 15:49:52.024  INFO 7848 --- [           main] o.s.b.d.a.OptionalLiveReloadServer       : LiveReload server is running on port 35729
2021-03-29 15:49:52.055  INFO 7848 --- [           main] o.s.b.devtools.RemoteSpringApplication   : Started RemoteSpringApplication in 2.52 seconds (JVM running for 4.236)
复制代码
  • 接下来我们再次修改下Controller中的测试代码,只要修改下message变量即可;
/**
 * Created by macro on 2021/3/25.
 */
@Api(tags = "TestController", description = "SpringBoot Dev Tools测试")
@Controller
@RequestMapping("/test")
public class TestController {

    @ApiOperation("测试修改")
    @RequestMapping(value = "/first", method = RequestMethod.GET)
    @ResponseBody
    public CommonResult first() {
        String message = "返回消息(远程调试)";
        return CommonResult.success(null,message);
    }
}
复制代码
  • 远程调试如果自动构建的话会导致远程服务频繁重启,此时我们可以使用IDEA手动构建,在项目的右键菜单中可以找到构建按钮;

  • 构建成功后可以发现远程服务会自动重启,并应用修改后的代码,访问测试接口返回如下信息;
{
  "code": 200,
  "message": "返回消息(远程调试)",
  "data": null
}
复制代码

总结

虽说使用SpringBoot官方的devtools可以进行热部署,但是这种方式更像是热重启,如果你想要更快的热部署体验的话可以使用JRebel。

项目源码地址

github.com/macrozheng/…

本文 GitHub github.com/macrozheng/… 已经收录,欢迎大家Star!



链接:https://juejin.cn/post/6955642563395223560

全部评论

相关推荐

我是小红是我:学校换成中南
点赞 评论 收藏
分享
牛客963010790号:为什么还要收藏
点赞 评论 收藏
分享
点赞 收藏 评论
分享
牛客网
牛客企业服务