基于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 IDEA的Spring 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

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • Spring Boot集成spring-boot-devtools开发时实现热部署的方式

    热部署是什么 大家都知道在项目开发过程中,常常会改动页面数据或者修改数据结构,为了显示改动效果,往往需要重启应用查看改变效果,其实就是重新编译生成了新的Class文件,这个文件里记录着和代码等对应的各种信息,然后Class文件将被虚拟机的ClassLoader加载. 而热部署正是利用了这个特点,它监听到如果有Class文件改动了,就会创建一个新的ClaassLoader进行加载该文件,经过一系列的过程,最终将结果呈现在我们眼前. 类加载机制 Java中的类经过编译器可以把代码编译为存储字节码的C

  • SpringBoot如何通过devtools实现热部署

    这篇文章主要介绍了SpringBoot如何通过devtools实现热部署,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 在项目的pom.xml文件添加如下两段 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <version>1

  • Springboot项目基于Devtools实现热部署步骤详解

    1.在pom.xml(如果是多模块,则此pom根据需要可设为具体模块)文件中添加 <dependency>     <groupId>org.springframework.boot</groupId>     <artifactId>spring-boot-devtools</artifactId>    <scope>runtime</scope>     <optional>true</option

  • Spring boot热部署devtools过程解析

    1 pom.xml文件 注:热部署功能spring-boot-1.3开始有的 <!--添加依赖--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <!-- optional=true,依赖不会传递,该项目依赖devtools:之后依赖myboot项目的项目如果想要使用d

  • 解决SpringBoot使用devtools导致的类型转换异常问题

    问题: 最近在使用新框架SpringBoot + shiro + spring-data-jpa时,为了体验下spring自带的热部署工具的便捷,于是引入了 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <!-- optional=true,依赖不会传递,该项目依赖devtools:

  • IntelliJ IDEA中SpringBoot项目通过devtools实现热部署的方法

    简要几个步骤: 一.添加依赖 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <optional>true</optional> </dependency> 二.开启热部署 <build> <plugins> <plugin&

  • SpringBoot实现devtools实现热部署过程解析

    1.修改pom.xml文件 <project> <dependencies> <!-- 使用devtool热部署插件(推荐) --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <optional>true</optional>

  • spring-boot中使用spring-boot-devtools的实现代码

    1. 什么是 spring-boot-devtools spring-boot-devtools 是 spring-boot项目开发时的一个热部署工具,安装了 spring-boot-devtools 依赖,我们在修改源代码后无需 mvn spring-boot:run 手动重启spring-boot项目,spring-boot-devtools 会自动帮我们重新启动项目. 默认情况下,spring-boot-devtools 会检测 项目文件夹的类路径上的所有文件.注意,某些资源(如静态资产和

  • 基于Spring Boot DevTools实现开发过程优化

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

  • 基于spring boot 的配置参考大全(推荐)

    如下所示: # =================================================================== # COMMON SPRING BOOT PROPERTIES # # This sample file is provided as a guideline. Do NOT copy it in its # entirety to your own application. ^^^ # =============================

  • 详解基于Spring Boot与Spring Data JPA的多数据源配置

    由于项目需要,最近研究了一下基于spring Boot与Spring Data JPA的多数据源配置问题.以下是传统的单数据源配置代码.这里使用的是Spring的Annotation在代码内部直接配置的方式,没有使用任何XML文件. @Configuration @EnableJpaRepositories(basePackages = "org.lyndon.repository") @EnableTransactionManagement @PropertySource("

  • spring Boot与Mybatis整合优化详解

    SpringBoot官方文档http://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/ 关于spring-boot与mybatis整合优化方面的介绍,就是Mybatis-Spring-boot-starter的介绍: 1.取消spring-mybatis.xml配置 ①自动检测已存在的Datasource 之前,需要在spring-mybatis.xml中配置datasource的Bean,现在只需要在applicat

  • 详解基于Spring Boot/Spring Session/Redis的分布式Session共享解决方案

    分布式Web网站一般都会碰到集群session共享问题,之前也做过一些Spring3的项目,当时解决这个问题做过两种方案,一是利用nginx,session交给nginx控制,但是这个需要额外工作较多:还有一种是利用一些tomcat上的插件,修改tomcat配置文件,让tomcat自己去把Session放到Redis/Memcached/DB中去.这两种各有优缺,也都能解决问题. 但是现在项目全线Spring Boot,并不自己维护Tomcat,而是由Spring去启动Tomcat.这样就会有一

  • 基于spring boot 1.5.4 集成 jpa+hibernate+jdbcTemplate(详解)

    1.pom添加依赖 <!-- spring data jpa,会注入tomcat jdbc pool/hibernate等 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <dependency> <

  • spring boot devtools在Idea中实现热部署方法

    1 pom.xml文件 注:热部署功能spring-boot-1.3开始有的 <!--添加依赖--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <!-- optional=true,依赖不会传递,该项目依赖devtools:之后依赖myboot项目的项目如果想要使用d

  • 基于Spring Boot不同的环境使用不同的配置方法

    spring 多文件配置: 1.properties文件 2.YAML文件 一.properties文件 在 Spring Boot 中, 多环境配置的文件名需要满足 application-{profile}. properties的格式, 其中{profile}对应你的环境标识, 如下所示. • application-dev.properties: 开发环境. • application-test.properties: 测试环境. • application-prod.propertie

  • 基于Spring Boot利用 ajax实现上传图片功能

    效果如下: 1.启动类中加入 SpringBoot重写addResourceHandlers映射文件路径 @Override public void addResourceHandlers(ResourceHandlerRegistry registry) { registry.addResourceHandler("/imctemp-rainy/**").addResourceLocations("file:D:/E/"); } 设置静态资源路径 2.   表单

  • Spring Boot DevTools使用教程

    DevTools通过提供自动重启和LiveReload功能,使您更快.更轻松地开发Spring Boot应用程序.除此之外,它还将各种属性设置为更适合本地开发的值.此外,它允许您远程连接到您的应用程序,并仍然使用其大部分功能.在生产中运行时,不要使用DevTools. 如何使用DevTools进一步加快Spring Boot开发速度?你需要做的就是添加正确的依赖关系,与Spring Boot一样,设置非常简单. 如果您使用Maven: <dependency> <groupId>o

随机推荐