Spring boot relies on application listeners and internal lifecycle event to decouple certain actions as the spring boots life cycle progresses.
Spring boot allows one to plugin a listener that is been called at each lifecycle event. You can see the main lifecycle events below:
In this article, we will add our own SpringApplicationRunListener
package com.javarticles.spring.utils;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.SpringApplicationRunListener;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.core.env.ConfigurableEnvironment;
public class CustomSpringApplicationRunListener implements SpringApplicationRunListener {
private SpringApplication app;
private String[] args;
public CustomSpringApplicationRunListener(SpringApplication app, String[] args){
this.app = app;
this.args = args;
}
@Override
public void starting() {
System.out.println("Custom SpringApplicationRunListener, starting");
}
@Override
public void environmentPrepared(ConfigurableEnvironment environment) {
System.out.println("Custom SpringApplicationRunListener, environment prepared");
}
@Override
public void contextPrepared(ConfigurableApplicationContext context) {
System.out.println("Custom SpringApplicationRunListener, context prepared");
}
@Override
public void contextLoaded(ConfigurableApplicationContext context) {
System.out.println("Custom SpringApplicationRunListener, context loaded");
}
@Override
public void started(ConfigurableApplicationContext context) {
System.out.println("Custom SpringApplicationRunListener, application started");
}
@Override
public void running(ConfigurableApplicationContext context) {
System.out.println("Custom SpringApplicationRunListener, running");
}
@Override
public void failed(ConfigurableApplicationContext context, Throwable exception) {
System.out.println("Custom SpringApplicationRunListener, failed!");
}
}
Most important here is that it should declared a constructor that accepts SpringApplication object and the string of arguments.
The other important point is the way it has to be integrated with spring boot application. In order for the spring boot application to find our listener, we need to follow spring factory loader approach where the fully qualified name of interface and its implementation must be specified in form of a property in spring.factories file. If more than one implementation, we need to specify them comma separated.
In our case here, create file META-INF/spring.factories in resources and add the below:
org.springframework.boot.SpringApplicationRunListener=com.javarticles.spring.utils.CustomSpringApplicationRunListener
When we run the application, now we can see the output of the custom listener.
Custom SpringApplicationRunListener, starting
Custom SpringApplicationRunListener, environment prepared
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.1.6.RELEASE)
Custom SpringApplicationRunListener, context prepared
2019-06-30 10:06:28.072 INFO 936 --- [ main] c.j.spring.utils.UtilsApplication : Starting UtilsApplication on INMAA1-L0156 with PID 936 (C:\Ram\springboot\utils\target\classes started by mokkara in C:\Ram\springboot\utils)
2019-06-30 10:06:28.076 INFO 936 --- [ main] c.j.spring.utils.UtilsApplication : No active profile set, falling back to default profiles: default
Custom SpringApplicationRunListener, context loaded
2019-06-30 10:06:28.460 INFO 936 --- [ main] c.j.spring.utils.UtilsApplication : Started UtilsApplication in 0.7 seconds (JVM running for 1.635)
Custom SpringApplicationRunListener, application started
Custom SpringApplicationRunListener, running