Spring Boot ApplicationReadyEvent
last modified July 6, 2020
Spring Boot ApplicationReadyEvent tutorial shows how to execute a task when an application is ready.
A Spring Boot application issues various events. We can use listeners to react to such events.
For instance, the ApplicationStartedEvent
is sent after the context has
been refreshed but before any application and command-line runners have been called.
The ApplicationReadyEvent
is sent after any application and command-line
runners have been called. It indicates that the application is ready to service requests.
Spring Boot ApplicationReadyEvent example
The following Spring Boot application is a simple web application that triggers
a web request in reaction to the ApplicationStartedEvent
. The request
is made with WebClient.
pom.xml src ├───main │ ├───java │ │ └───com │ │ └───zetcode │ │ │ Application.java │ │ ├───bean │ │ │ TimeResponse.java │ │ ├───event │ │ │ AppEvents.java │ │ └───route │ │ AppRoutes.java │ └───resources └───test └───java └───com └───zetcode └───route AppRoutesTest.java
This is the project structure.
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.zetcode</groupId> <artifactId>SpringBootApplicationReadyEvent</artifactId> <version>1.0-SNAPSHOT</version> <packaging>jar</packaging> <properties> <java.version>13</java.version> </properties> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.2.4.RELEASE</version> </parent> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-webflux</artifactId> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
This is the Maven build file. The spring-boot-starter-webflux
is starter for
building WebFlux applications using Spring Framework's Reactive Web support.
package com.zetcode.bean; public class TimeResponse { private String date; private Long unixtime; private String time; public String getDate() { return date; } public void setDate(String date) { this.date = date; } public Long getUnixtime() { return unixtime; } public void setUnixtime(Long unixtime) { this.unixtime = unixtime; } public String getTime() { return time; } public void setTime(String time) { this.time = time; } @Override public String toString() { final StringBuilder sb = new StringBuilder("TimeResponse{"); sb.append("date='").append(date).append('\''); sb.append(", unixtime=").append(unixtime); sb.append(", time='").append(time).append('\''); sb.append('}'); return sb.toString(); } }
This is the TimeResponse
bean. It is used to store data
from the web request.
package com.zetcode.event; import com.zetcode.bean.TimeResponse; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.boot.context.event.ApplicationReadyEvent; import org.springframework.context.event.EventListener; import org.springframework.stereotype.Component; import org.springframework.web.reactive.function.client.WebClient; import reactor.core.publisher.Mono; @Component public class AppEvents { private static final Logger logger = LoggerFactory.getLogger(AppEvents.class); @EventListener(ApplicationReadyEvent.class) public void startApp() { var webClient = WebClient.create("http://time.jsontest.com/"); Mono<TimeResponse> result = webClient.get() .retrieve() .bodyToMono(TimeResponse.class); result.subscribe(res -> logger.info("{}", res)); } }
In AppEvents
we create a simple GET request.
@EventListener(ApplicationReadyEvent.class) public void startApp() {
With @EventListener
annotation, we register for the ApplicationReadyEvent
.
var webClient = WebClient.create("http://time.jsontest.com/");
From the http://time.jsontest.com/
, we get the current time.
Mono<TimeResponse> result = webClient.get() .retrieve() .bodyToMono(TimeResponse.class); result.subscribe(res -> logger.info("{}", res));
With WebClient
, we create a GET request to the site and output
the result to the terminal.
package com.zetcode.route; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.reactive.function.server.RouterFunction; import org.springframework.web.reactive.function.server.ServerResponse; import static org.springframework.web.reactive.function.server.RequestPredicates.GET; import static org.springframework.web.reactive.function.server.RouterFunctions.route; import static org.springframework.web.reactive.function.server.ServerResponse.ok; @Configuration public class AppRoutes { @Bean RouterFunction<ServerResponse> home() { return route(GET("/"), request -> ok().bodyValue("Home page")); } }
Our application uses a functional web framework to return a simple message for the home page.
package com.zetcode; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } }
The Application
sets up the Spring Boot application
package com.zetcode.route; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; import org.springframework.test.web.reactive.server.WebTestClient; @RunWith(SpringRunner.class) @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) public class AppRoutesTest { @Autowired private WebTestClient client; @Test public void test_home_page() { client.get().uri("/").exchange().expectStatus().isOk() .expectBody(String.class).isEqualTo("Home page"); } }
With WebTestClient
, we create a test method for the home page.
... 2019-06-21 16:40:45.214 INFO 9356 --- [ctor-http-nio-5] com.zetcode.event.AppEvents : TimeResponse{date='06-21-2019', unixtime=null, time='02:40:47 PM'} ...
When the application starts, we get this message to the terminal.
In this tutorial, we have worked with ApplicationReadyEvent
.