Accelerate SpringBoot application development, the official hot deployment tool is awesome!

Usually when you develop applications with SpringBoot, you need to restart the application after modifying the code to take effect. If your application is big enough, it may take several minutes to start. Is there any way to speed up the startup process and make our application code development more efficient? Today we recommend you an official SpringBoot hot deployment tool spring-boot-devtools that can quickly and automatically restart your application after modifying the code!

SpringBoot hands-on e-commerce project mall (40k+star) address: https://github.com/macrozheng/mall

1. Introduction to spring-boot-devtools

SpringBoot official development tools, if your application integrated with it, you can achieve hot deployment and remote debugging.

1.1 Realization Principle

Why does the application start faster with this tool? Mainly because it uses two different class loaders. The base class loader is used to load classes that won’t change (like classes in third-party libraries), and the restart class loader is used to load the classes in your application. When the application starts, the classes in the restart class loader will be replaced, which means that restarts will be faster than cold starts!

1.2 Hot Deployment

Next we will integrate devtools to demonstrate the hot deployment feature.

First you need to add the devtools dependency to the project’s pom.xml file.

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

To facilitate testing, we have added the following test interface to the project.

/**
 * Created by macro on 2021/3/25.
 */
@Api(tags = "TestController", description = "SpringBoot Dev Tools Test")
@Controller
@RequestMapping("/test")
public class TestController {

    @ApiOperation("Test Modification")
    @RequestMapping(value = "/first", method = RequestMethod.GET)
    @ResponseBody
    public CommonResult first() {
        String message = "Return Message";
        return CommonResult.success(null,message);
    }
}

Then start the project and access the interface through Swagger after a successful start and return the following results, accessed at http://localhost:8088/swagger-ui.html

{
  "code": 200,
  "message": "Return Message",
  "data": null
}

Since devtools only automatically restarts the project when the project is built, and IDEA does not use auto-build by default, we can modify the application startup configuration to set the project to automatically build when IDEA loses focus.

To modify the code in the Controller, just change the message variable.

/**
 * Created by macro on 2021/3/25.
 */
@Api(tags = "TestController", description = "SpringBoot Dev Tools Test")
@Controller
@RequestMapping("/test")
public class TestController {

    @ApiOperation("Test Modification")
    @RequestMapping(value = "/first", method = RequestMethod.GET)
    @ResponseBody
    public CommonResult first() {
        String message = "Return message (modified)";
        return CommonResult.success(null,message);
    }
}

After losing focus and waiting for the project to build automatically, there is a 404 problem accessing the interface at this time.

{
  "timestamp": "2021-03-29T07:09:05.415+00:00",
  "status": 404,
  "error": "Not Found",
  "message": "No message available",
  "path": "/test/first"
}

Due to the difference between the detection time of devtools and the compilation time of IDEA, when IDEA has not finished compiling, devtools has already restarted the application, which causes this problem, modify the application.yml configuration file and add the following configuration.

spring:
  devtools:
    restart:
      poll-interval: 2s
      quiet-period: 1s

At this time, the test interface is accessed again and the following content is displayed, and the modified code has been applied automatically.

{
  "code": 200,
  "message": "Return message (modified)",
  "data": null
}

2. Remote Debugging

devtools supports remote debugging in addition to hot deployment, so let’s deploy the application to a Docker container and try remote debugging!

Since SpringBoot does not include devtools in its default packaging, we need to modify the pom.xml first.

<plugin>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-maven-plugin</artifactId>
    <configuration>
        <!--Devtools are not excluded when packaging-->
        <excludeDevtools>false</excludeDevtools>
    </configuration>
</plugin>

Next, the application.yml file is needed, adding the remote access password for devtools.

spring:
  devtools:
    remote:
      secret: macro666

Next, package the project as a Docker image and run it up using the following command.

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

Add a startup configuration, modify the startup class to org.springframework.boot.devtools.RemoteSpringApplication, and configure the information as follows.

Start this configuration and the console outputs the following result indicating a successful remote connection.

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)

Next, we modify the test code in the Controller again, simply by modifying the message variable.

/**
 * Created by macro on 2021/3/25.
 */
@Api(tags = "TestController", description = "SpringBoot Dev Tools Test")
@Controller
@RequestMapping("/test")
public class TestController {

    @ApiOperation("Test Modification")
    @RequestMapping(value = "/first", method = RequestMethod.GET)
    @ResponseBody
    public CommonResult first() {
        String message = "Return message (remote debugging)";
        return CommonResult.success(null,message);
    }
}

Remote debugging will lead to frequent restarts of the remote service if it is built automatically, at this point we can use IDEA to build manually, the build button can be found in the right-click menu of the project.

A successful build reveals that the remote service will automatically restart and apply the modified code, and access the test interface returning the following information.

{
  "code": 200,
  "message": "Return message (remote debugging)",
  "data": null
}

3. Summary

Although hot deployment is possible using SpringBoot’s official devtools, this is more like a hot restart, so you can use JRebel if you want a faster hot deployment experience.

Project source code address: https://github.com/macrozheng/mall-learning/tree/master/mall-tiny-devtools

Leave a Reply