Sunday 20 October 2019

Spring boot Dev tools: Automatic Restart of the Application


If you add 'spring-boot-devtools' to your application, then application will automatically restart whenever files on the classpath are changed.

Is the changes in static files (like html, images) require restart?
Some resources do not require a restart when they are changed.  For example, changing the resources in /META-INF/maven, /META-INF/resources, /resources, /static, /public, or /templates folders does not trigger a restart but trigger a live reload (It trigger a browser refresh whenever a resource is changed).

Note
If you want to disable live reload functionality set the property spring.devtools.livereload.enabled to false.

How to restarts work internally?
Spring boot uses two class loaders to work with restarts.
a.   Base Classloader
b.   Restart Classloader

Base Classloader
Classes that do not change (for example, those from third-party, spring core jars) are loaded into a base classloader.

Restart Classloader
All your application specific classes are loaded using restart classloader. Whenever restart is required, existing restarting class loader gets destroyed and new classloader gets created.

Let’s see the automatic restart functionality using an example.

Step 1: Create a template project.
Go to 'https://start.spring.io/'.

Give the group as 'com.sample.app', Artifact as 'DevToolDemo'.

Add below dependencies.
a.   Spring Web Starter
b.   Spring Boot DevTools


Click on ‘Generate the project’ button.

Extract the downloaded zip file.

Step 2: Import the maven project from step 1 to Eclipse.
Imported project structure looks like below.


Step 3: Add controller.

Create a package 'com.sample.app.DevToolDemo.controller' and define HomeController.java like below.

HomeController.java
package com.sample.app.DevToolDemo.controller;

import java.util.Iterator;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.AbstractEnvironment;
import org.springframework.core.env.Environment;
import org.springframework.core.env.MapPropertySource;
import org.springframework.core.env.PropertySource;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.*;

@RestController
public class HomeController {

    @Autowired
    private Environment env;

    @RequestMapping("/")
    public String homePage() {
        return "Welcome to Spring boot Application Development";
    }

    @RequestMapping("/configs")
    public Map<String, Object> configs() {
        Map<String, Object> properties = new HashMap<>();

        Iterator iterator = ((AbstractEnvironment) env).getPropertySources().iterator();

        while(iterator.hasNext()) {
            PropertySource propertySource = (PropertySource) iterator.next();
            
            if (propertySource instanceof MapPropertySource) {

                String[] propertyNames = ((MapPropertySource) propertySource).getPropertyNames();

                for (String propName : propertyNames) {
                    properties.put(propName, propertySource.getProperty(propName));
                }

            }

        }
        
        return properties;
    }

}

Step 4: Create ‘application.properties’ file under src/main/resources folder.

application.properties
server.port=9999


DevToolDemoApplication.java
package com.sample.app.DevToolDemo;

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

@SpringBootApplication
public class DevToolDemoApplication {

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

}


Total project structure looks like below.

Run DevToolDemoApplication.java.   

Open the url 'http://localhost:9999/' in browser, you can see below kind of screen.


Now update the application.properties file by changing the port number from 9999 to 8888, save the file.

Once you save the file, you can see that application restart is triggered by spring boot and you can see below messages in console.
2019-09-04 13:23:03.171  INFO 85555 --- [       Thread-6] o.s.s.concurrent.ThreadPoolTaskExecutor  : Shutting down ExecutorService 'applicationTaskExecutor'

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v2.1.7.RELEASE)

2019-09-04 13:23:03.304  INFO 85555 --- [  restartedMain] c.s.a.D.DevToolDemoApplication           : Starting DevToolDemoApplication on C02X902SJGH5 with PID 85555 (/Users/krishna/Downloads/DevToolDemo/target/classes started by krishna in /Users/krishna/Downloads/DevToolDemo)
2019-09-04 13:23:03.305  INFO 85555 --- [  restartedMain] c.s.a.D.DevToolDemoApplication           : No active profile set, falling back to default profiles: default
2019-09-04 13:23:03.456  INFO 85555 --- [  restartedMain] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port(s): 8888 (http)
2019-09-04 13:23:03.457  INFO 85555 --- [  restartedMain] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
2019-09-04 13:23:03.457  INFO 85555 --- [  restartedMain] org.apache.catalina.core.StandardEngine  : Starting Servlet engine: [Apache Tomcat/9.0.22]
2019-09-04 13:23:03.462  INFO 85555 --- [  restartedMain] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
2019-09-04 13:23:03.462  INFO 85555 --- [  restartedMain] o.s.web.context.ContextLoader            : Root WebApplicationContext: initialization completed in 156 ms
2019-09-04 13:23:03.502  INFO 85555 --- [  restartedMain] o.s.s.concurrent.ThreadPoolTaskExecutor  : Initializing ExecutorService 'applicationTaskExecutor'
2019-09-04 13:23:03.531  INFO 85555 --- [  restartedMain] o.s.b.d.a.OptionalLiveReloadServer       : LiveReload server is running on port 35729
2019-09-04 13:23:03.542  INFO 85555 --- [  restartedMain] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 8888 (http) with context path ''
2019-09-04 13:23:03.543  INFO 85555 --- [  restartedMain] c.s.a.D.DevToolDemoApplication           : Started DevToolDemoApplication in 0.252 seconds (JVM running for 125.771)
2019-09-04 13:23:03.544  INFO 85555 --- [  restartedMain] .ConditionEvaluationDeltaLoggingListener : Condition evaluation unchanged


Open the url ‘http://localhost:8888/’ in browser, you can see below kind of screen.

Previous                                                    Next                                                    Home

No comments:

Post a Comment