Spring Boot
Application Lifecycle
Java
Post Initialization
Startup Logic

Running code after Spring Boot starts

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

When working with a Spring Boot application, there might be specific tasks or operations that you would like to execute once the application context is fully initialized and the application is ready to service requests. These tasks can range from preloading data, initializing caches, or starting background jobs. This article delves into various mechanisms provided by Spring Boot to run code after the application has started.

Runnable Interface

The simplest way to execute code after your Spring Boot application has started is to implement the Runnable interface within a @Component. Spring Boot will automatically detect and run any beans implementing the Runnable interface using a CommandLineRunner or ApplicationRunner.

Using CommandLineRunner

CommandLineRunner is triggered once the application context has been loaded. It provides access to the application's command-line arguments.

java
1import org.springframework.boot.CommandLineRunner;
2import org.springframework.stereotype.Component;
3
4@Component
5public class StartupRunner implements CommandLineRunner {
6
7    @Override
8    public void run(String... args) throws Exception {
9        System.out.println("Executing startup tasks...");
10        // Execute your logic here
11    }
12}

Using ApplicationRunner

If you need to customize how command-line arguments are handled, use the ApplicationRunner interface. It employs the ApplicationArguments class, which provides a more structured way to retrieve arguments.

java
1import org.springframework.boot.ApplicationArguments;
2import org.springframework.boot.ApplicationRunner;
3import org.springframework.stereotype.Component;
4
5@Component
6public class StartupApplicationRunner implements ApplicationRunner {
7
8    @Override
9    public void run(ApplicationArguments args) throws Exception {
10        System.out.println("Executing startup tasks with ApplicationRunner...");
11        System.out.println("Option names: " + args.getOptionNames());
12        // Execute your logic here
13    }
14}

Using @EventListener for ApplicationReadyEvent

Another common approach to execute code after the application starts is to listen for the ApplicationReadyEvent. This event is fired once the application is completely initialized.

java
1import org.springframework.boot.context.event.ApplicationReadyEvent;
2import org.springframework.context.event.EventListener;
3import org.springframework.stereotype.Component;
4
5@Component
6public class AppStartupEventListener {
7
8    @EventListener
9    public void onApplicationReady(ApplicationReadyEvent event) {
10        System.out.println("Application is fully started and ready to service requests.");
11        // Execute your logic here
12    }
13}

Scheduling Tasks with @Scheduled

For recurring tasks or when your startup logic needs to be executed periodically, consider using Spring's @Scheduled annotation. Tasks can be scheduled with fixed delays, fixed rates, or cron expressions.

First, ensure you have enabled scheduling in your application by adding @EnableScheduling in one of your configuration classes.

java
1import org.springframework.scheduling.annotation.EnableScheduling;
2import org.springframework.scheduling.annotation.Scheduled;
3import org.springframework.stereotype.Component;
4
5@Component
6@EnableScheduling
7public class ScheduledTasks {
8
9    @Scheduled(fixedRate = 5000)
10    public void performTask() {
11        System.out.println("Scheduled task executing every 5 seconds...");
12    }
13
14    @Scheduled(cron = "0 0 * * * ?")
15    public void performTaskUsingCron() {
16        System.out.println("Scheduled task executed at the top of every hour...");
17    }
18}

Key Points Summary

MechanismPurposeExample Use Case
CommandLineRunnerExecute immediately after the application context is loaded using command-line arguments.Preloading initial data.
ApplicationRunnerSimilar to CommandLineRunner but offers more structured argument handling.More complex argument-dependent tasks.
ApplicationReadyEventExecute code once the application is fully ready to process requests.Initialize services needing full startup.
@ScheduledExecute repetitive tasks using fixed rates or cron expressions.Periodic data clean-up or maintenance.

Additional Considerations

  1. Asynchronous Execution: If the startup task is time-consuming and should not block the application’s readiness, consider using @Async to run the code asynchronously. Ensure that @EnableAsync is added to one of the configuration classes.
java
1   import org.springframework.scheduling.annotation.Async;
2   import org.springframework.stereotype.Component;
3
4   @Component
5   public class AsyncStartupTask {
6
7       @Async
8       public void performAsyncTask() {
9           // This task runs asynchronously
10           System.out.println("Executing an asynchronous task...");
11       }
12   }
  1. Transaction Management: For database operations during startup, ensure proper transaction management. Use @Transactional to ensure consistency and rollback capabilities.
  2. Error Handling: Implement adequate error handling and logging mechanisms during startup to handle and trace issues effectively.
  3. Profile Specific Initialization: Utilize Spring profiles to conditionally run startup tasks relevant to different environments (e.g., dev, test, prod).

By understanding these mechanisms and utilizing them appropriately, you can ensure that your Spring Boot application efficiently initializes any necessary services or configurations, ultimately leading to smoother application operations.


Course illustration
Course illustration

All Rights Reserved.