专栏首页TECH flower使用Spring Boot DevTools优化你的开发体验

使用Spring Boot DevTools优化你的开发体验

场景再现

某日少年收到前端同学发来的消息说联调的接口响应异常?,少年表现的很平静?,因为这种事情太平常了?。于是询问详情之后开始打开自己的代码查找问题所在,没过五分钟就发现了问题。少年修改完代码之后将本地启动的项目停止然后再重新启动。由于当前的服务端项目是一个巨大的单体应用,启动需要花三四分钟时间,于是少年就拿出手机开始刷起朋友圈。刷着刷着(由于注意力分散不知不觉花了十几分钟)突然意识到项目已经重新启动,于是通知前端同学查看效果。

分析问题

上面的场景可能对很多开发者来说感同身受,在开发中修改项目是很平常且频繁的一件事情。当我们修改完代码或其他文件的时候,我们会重新启动项目来验证修改是否真的生效(这里忽略我们编写的测试代码),以供前端或者其他客户端来使用我们的修改。但是不知不觉这样的流程浪费了我们很多时间,甚至被迫分散我们的注意力(打开社交软件、看新闻、和同事聊天),这些问题对我们的生产力是一个极大的威胁。

spring-boot-devtools

能否有一种方案可以让我们对项目的修改快速生效,从而节省那些我们本该可以利用的时间呢?幸好有一种工具可以解决当前所存在的问题,这就是Spring Boot Dev Tools

原理简介

您可能会说,了解Spring Boot Dev Tools的工作原理并不重要,但是由于开发过程中存在很多复杂的情况,所以了解Spring Boot Dev Tools的工作原理是对我们有帮助的。

Spring Boot Dev Tools钩接(hooks into)到Spring Boot的类加载器中,以提供一种方法来按需重新启动应用程序上下文或重新加载已更改的静态文件而无需重新启动整个应用程序。

为此,Spring Boot Dev Tools将划分应用程序的类路径并分配给两个不同的类加载器:

  • 基本类加载器(base classloader):包含一些不可变类或者几乎不会被修改文件,例如Spring Boot JAR或第三方库。
  • 重新启动类加载器(restart classloader):包含应用程序的文件,这些文件在项目开发过程中将频繁更改。

重新启动应用程序后,现有的重新启动类加载器将被丢弃,新的重新启动类加载器将被启动。这种方法意味着应用程序的重启通常比“冷启动”要快得多,因为基本类加载器没有受到影响并且一直存在着。

引入依赖

当我们使用intellij IDEASpring Initializr创建项目时,Spring Initializr提供了内置的Spring Boot Dev Tools依赖选项,我们只需选择它即可。

Spring Initializr中引入Spring Boot Dev Tools

Maven项目中引入Spring Boot Dev Tools

在项目的pom.xml文件中引入Spring Boot Dev Tools依赖即可

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-devtools</artifactId>
    <scope>runtime</scope>
    <optional>true</optional>
</dependency>

项目演示

单模块

在项目中添加一个简单的Controller

@SpringBootApplication
public class DevToolApplication {

    public static void main(String[] args) {
        SpringApplication.run(DevToolApplication.class, args);
    }

    @RestController
    public static class HelloWorld {
        @GetMapping("test")
        public ResponseEntity<?> getTest() {
            return ResponseEntity.ok("hello world");
        }
    }
}

启动项目,访问http://localhost:8080/test,返回如下:

我们简单修改代码

@RestController
public static class HelloWorld {
    @GetMapping("test")
    public ResponseEntity<?> getTest() {
        return ResponseEntity.ok("hello world after change file");
    }
}

运行命令mvn compile,运行完毕重新访问http://localhost:8080/test

可以看到,我们的更改已经生效了。

多模块

假设现在我们的项目引用了其他项目作为子模块

<dependency>
    <groupId>org.example</groupId>
    <artifactId>untitled</artifactId>
    <version>1.0-SNAPSHOT</version>
</dependency>

我们需要在程序运行时,对上述子模块的修改也即时生效。

在多模块项目中使用Spring Boot Dev Tools比单模块项目略复杂,由于在多模块项目中主模块对子模块是引用关系,并且在运行时主模块通过引用子模块的jar文件的形式来启动应用程序,根据前面Spring Boot Dev Tools的原理,jar文件的加载将归属于基本类加载器,因此按照现在的做法无法做到子模块的修改即时生效。

不过Spring Boot Dev Tools提供了对多模块项目的支持,我们只需要添加简单的配置即可实现多模块项目的修改即时生效。

在项目的/resources中创建META-INF/spring-devtools.properties文件,并添加配置

restart.include.projectcommon=/untitled-1.0-SNAPSHOT.jar

上述配置表明重新启动类加载器在重新启动的时候,会加载最新的子模块依赖,从而做到子模块的修改即时生效。

现在子模块中存在如下类

public class DemoA {
    private String name;

    public String getName() {
        return name;
    }

    public DemoA setName(String name) {
        this.name = name+"cgsj111";
        return this;
    }
}

主模块中引用了上面的类

@RestController
public static class HelloWorld {
    @GetMapping("test")
    public ResponseEntity<?> getTest() {
        DemoA demo = new DemoA();
        demo.setName("demo name");
        return ResponseEntity.ok(demo);
    }
}

此时启动应用程序,访问http://localhost:8080/test

可以看到响应正常返回,此时我们修改子模块的代码

public class DemoA {
    private String name;

    public String getName() {
        return name;
    }

    public DemoA setName(String name) {
        this.name = name+"cgsj111 After Change";
        return this;
    }
}

然后在主模块中运行命令 mvn compile,此时再次访问接口

可以看到子模块的修改已经在主模块中即时生效了。

远程调试

Spring Boot Dev Tools所展现的高效便捷之处不仅仅局限于本地调试,对于远程调试也有很好的支持。选择性地启用远程支持是因为启用它可能会带来安全风险。仅当在受信任的网络上运行或使用SSL保护时,才应启用它。如果这两个选项都不满足,则不应使用DevTools的远程支持。您永远不应该在生产环境中启用他。

启用它需要确保构建物中包含devtools,修改至如下配置:

<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
            <configuration>
                <!--确保项目打包是将Devtools包含进去-->
                <excludeDevtools>false</excludeDevtools>
            </configuration>
        </plugin>
    </plugins>
</build>

然后,您需要设置spring.devtools.remote.secret属性。像任何重要的密码或机密一样,该值应唯一且强壮,以免被猜测或强行使用,例如,在application.properties中设置:

spring.devtools.remote.secret=cgsj8377

远程devtools支持分为两部分:接受连接的服务器端端点和在IDE中运行的客户端应用程序。设置spring.devtools.remote.secret属性后,将自动启用服务器组件,客户端组件必须手动启动。

调试演示

在项目文件夹中运行命令 mvn package生成jar文件,将jar文件部署到服务器(在这里我们以本地运行jar包的方式来模拟远程部署)。然后在IDE进行如下配置(以Intellij IDEA为例)

如上图我们添加了一个启动器,启动类为org.springframework.boot.devtools.RemoteSpringApplication,并且传递了一个程序参数来指定远程应用程序的地址,此处笔者在本机上试验所以是一个本机的地址。

接下来我们启动我们刚刚创建的启动器

启动日志如下

修改代码至如下

@RestController
public static class HelloWorld {
    @GetMapping("test")
    public ResponseEntity<?> getTest() {
        DemoA demo = new DemoA();
        demo.setName("remote test");
        return ResponseEntity.ok(demo);
    }
}

然后运行命令mvn compile,可以看到我们的更改在运行的程序中即时生效了

总结

在我们的日常的开发过程中总会存在各种各样的“等待”,这些时刻很大程度上会影响开发者的效率和注意力。而Developer Tools的出现缓解了这个问题,他使应用程序的调试更加的便捷高效。有一点要注意的是在让我们的更改生效之前需要执行mvn compile命令,从而使本地代码能被编译成程序可以理解的字节码文件。

本文示例代码:https://gitee.com/jeker8chen/dev-tool

本文参考资料:

https://docs.spring.io/spring-boot/docs/current/reference/html/using-spring-boot.html#using-boot-devtools

https://reflectoring.io/spring-boot-dev-tools/

本文分享自微信公众号 - TECH flower(tech-flower),作者:东溪陈姓少年

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2020-08-24

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • spring Boot 配置文件详解

    概要        前面我们讲述了如何搭建一个简单的 spring Boot 应用(参见Spring Boot - 初探),这里,我们来学习如何对项目进行相关的...

    xiangzhihong
  • Spring Boot系列 – 1. 简介

    本文主要介绍以下几部分:  1. 什么是spring Boot?  2. 为什么使用Spring Boot?  3. Spring Boot提供哪些功能...

    Java架构师必看
  • Java面试——Spring Boot

    简单说说我的理解:Java是一个静态语言,相比动态语言,它相对笨重,体现在我们搭建 SSM 框架写一个 Helloword 的时候相当复杂,需要写一大堆的配置。...

    Java架构师必看
  • Spring Boot devtool的使用

    Spring Boot为我们提供了一个便捷的开发Spring Boot应用程序的环境,同时为了方便我们的开发Spring Boot应用程序,Spring Boo...

    程序那些事
  • Spring-boot特性(1) 原

    spring-boot还是建议按照标准的controller-service-dao结构分层。有一个独立的Application.java作为系统启动入口。

    随风溜达的向日葵
  • 体验spring-boot-devtools热部署,流畅且不失强大

    哈喽?多么土多么俗多么没有档次,就像是嘴里含了个槟郎,吐不出气来,绝对需要进行改正。

    xjjdog
  • Spring Boot从零入门7_最新配置文件配置及优先级详细介绍

    本文属于原创,转载注明出处,欢迎关注微信小程序小白AI博客 微信公众号小白AI或者网站 https://xiaobaiai.net 或者我的CSDN http:...

    别打名名
  • 重学SpringBoot系列之基础知识回顾

    首先你需要明白一件事情:Spring Boot项目目的并不是替换Spring、SpringMVC,而是使他们用起来更加简单。

    大忽悠爱学习
  • Spring Boot 五种热部署方式,极速开发就是生产力!

    在 Spring Boot 中,模板引擎的页面默认是开启缓存的,如果修改了页面的内容,则刷新页面是得不到修改后的页面的,因此我们可以在application.p...

    Java技术栈
  • Spring Boot DevTools使用教程

    DevTools通过提供自动重启和LiveReload功能,使您更快、更轻松地开发Spring Boot应用程序。除此之外,它还将各种属性设置为更适合本地开发的...

    lyb-geek
  • Spring Boot 中的热部署方式总结

    在 Spring Boot 中,模板引擎的页面默认是开启缓存的,如果修改了页面的内容,则刷新页面是得不到修改后的页面的,因此我们可以在application.p...

    程序员小强
  • Spring Boot 五种热部署方式,再也不用老重启了!

    在 Spring Boot 中,模板引擎的页面默认是开启缓存的,如果修改了页面的内容,则刷新页面是得不到修改后的页面的,因此我们可以在application.p...

    JAVA葵花宝典
  • Spring Boot 五种热部署方式,再也不用老重启了!

    在 Spring Boot 中,模板引擎的页面默认是开启缓存的,如果修改了页面的内容,则刷新页面是得不到修改后的页面的,因此我们可以在application.p...

    趣学程序-shaofeer
  • Spring Boot 五种热部署方式,极速开发就是生产力!

    在 Spring Boot 中,模板引擎的页面默认是开启缓存的,如果修改了页面的内容,则刷新页面是得不到修改后的页面的,因此我们可以在application.p...

    程序IT圈
  • 体验spring-boot-devtools热部署,流畅且不失强大,Jrebel呢?

    一个高级开发工程师,第一次用SpringBoot,决定打印一个经典的HelloWorld。

    用户4172423
  • 第9章 Spring Boot开发者工具第9章 Spring Boot开发者工具

    Spring Boot Maven Plugin,提供了使用Maven构建Spring Boot 工程的支持。我们可以用这个插件完成打包功能。支持打可执行jar...

    一个会写诗的程序员
  • SpringBoot 五种热部署方式,提高生产效率

    在SpringBoot中,模板引擎的页面默认是开启缓存的,如果修改了页面的内容,则刷新页面是得不到修改后的页面的,因此我们可以在application.prop...

    java进阶架构师
  • Spring boot热部署(三)

    CTRL + SHIFT + A --> 查找make project automatically --> 选中

    楠楠
  • Spring Boot 五种热部署方式,提高生产效率

    在SpringBoot中,模板引擎的页面默认是开启缓存的,如果修改了页面的内容,则刷新页面是得不到修改后的页面的,因此我们可以在application.prop...

    搜云库技术团队

扫码关注云+社区

领取腾讯云代金券