Spring Boot ApplicationReadyEvent

last modified July 29, 2023

In this article we show 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.

│   ├───java
│   │   └───com
│   │       └───zetcode
│   │           │   Application.java
│   │           ├───bean
│   │           │       TimeResponse.java
│   │           ├───event
│   │           │       AppEvents.java
│   │           └───route
│   │                   AppRoutes.java
│   └───resources

This is the project structure.

plugins {
    id 'java'
    id 'org.springframework.boot' version '3.1.1'
    id 'io.spring.dependency-management' version '1.1.0'

group = 'com.zetcode'
version = '0.0.1-SNAPSHOT'

java {
    sourceCompatibility = '17'

repositories {

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-webflux'
    testImplementation 'org.springframework.boot:spring-boot-starter-test'

test {

This is the Gradle 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;

    public String toString() {

        final StringBuilder sb = new StringBuilder("TimeResponse{");
        sb.append(", unixtime=").append(unixtime);
        sb.append(", time='").append(time).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;

public class AppEvents {

    private static final Logger logger = LoggerFactory.getLogger(AppEvents.class);

    public void startApp() {

        var webClient = WebClient.create("http://time.jsontest.com/");

        Mono<TimeResponse> result = webClient.get()

        result.subscribe(res -> logger.info("{}", res));

In AppEvents we create a simple GET request.

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()

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;

public class AppRoutes {

    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;

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.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.web.reactive.server.WebTestClient;

@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class AppRoutesTest {

    private WebTestClient client;

    public void test_home_page() {

                .expectBody(String.class).isEqualTo("Home page");

With WebTestClient, we create a test method for the home page.

... com.zetcode.event.AppEvents: TimeResponse{date='07-18-2023', unixtime=null, time='11:02:38 AM'}

When the application starts, we get this message to the terminal.

In this article we have worked with ApplicationReadyEvent.


My name is Jan Bodnar and I am a passionate programmer with many years of programming experience. I have been writing programming articles since 2007. So far, I have written over 1400 articles and 8 e-books. I have over eight years of experience in teaching programming.

List all Spring Boot tutorials.