CommandLineRunner interface

Spring boot provides CommandLineRunner interface located in org.springframework.boot package.
CommandLineRunner allows you to run code after the application context has been fully loaded.

It is an effective way to perform tasks at spring boot application startup such as

  • data initialization,
  • establishing database connections,
  • performing validations etc.

Spring docs state,

Interface used to indicate that a bean should run when it is contained within SpringApplication.

When a class or bean implements CommandLineRunner interface, it needs to implement its run() method.
run() is automatically invoked after Spring ApplicationContext is initialized.
Its signature is

void run(String... args) throws Exception;

Note that the argument of run() is a string array.
This is the same array that is supplied to the main method of spring boot application.
So, you can get access to application arguments inside a class that implements CommandLineRunner.

CommandLineRunner example
Below is an example of a bean that implements CommandLineRunner and implements its run() method.

import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;

@Component
public class MyRunner implements CommandLineRunner {

  @Override
  public void run(String... args) throws Exception {
    // add your startup code here
    System.out.println("Application started!");
  }
}

You can provide your own custom logic inside run() that is specific to your application.

Remember that it is up to you how the bean implementing CommandLineRunner interface is registered, since there are many ways to create a bean in spring.
Error handling
If you look at the signature of run(), it declares to throw an exception.
So, if an exception arises in run() and it is not handled, then it will propagate above and prevent the application from starting up.
Thus, it is important that exception should be handled properly inside run().
There are following two ways to handle exception in run().
1. Using try-catch
This is a standard exception handling mechanism of java, where you enclose the code that might generate an exception between try-catch block.

import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;

@Component
public class AppInitializer implements CommandLineRunner {

  @Override
  public void run(String... args) throws Exception {
    try {
      // code
    } catch (Exception e) {
      // handle exception
      System.err.println("Error: " + e.getMessage());
    }
  }
}

2. Using ExitCodeGenerator
Spring boot provides an ExitCodeGenerator interface, which allows you to return an integer value, which is the exit code for in case an error occurs.
It contains getExitCode() method that returns a non-zero value (such as 1) to indicate an error condition.

import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.ExitCodeGenerator;
import org.springframework.stereotype.Component;

@Component
public class AppInitializer implements CommandLineRunner, 
                                       ExitCodeGenerator {

  @Override
  public void run(String... args) throws Exception {
    // code
  }

  @Override
  public int getExitCode() {
    // return non-zero exit code to indicate an error
    return 1; 
  }
}

Spring boot automatically detects the presence of an exit code generator.
When an exception occurs in CommandLineRunner bean’s run() method, it calls getExitCode() method to determine the application’s exit code.

Order of Execution
It might be possible that multiple classes implement CommandLineRunner interface in the same application.
Also, they might need to be executed in a specific order.

This can be done using @Order annotation over the class implementing CommandLineRunner.
@Order is followed by a numeric value between parenthesis.
The bean having a lower order value is executed before the bean having a higher order value.

import org.springframework.boot.CommandLineRunner;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

@Component
@Order(1)
public class ConnectionInitializer implements CommandLineRunner {

  @Override
  public void run(String... args) throws Exception {
    // code
    System.out.println("Connections initialized.");
  }
}
import org.springframework.boot.CommandLineRunner;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

@Component
@Order(2)
public class DataInitializer implements CommandLineRunner {

  @Override
  public void run(String... args) throws Exception {
    // code
    System.out.println("Data initialized.");
  }
}

In above example, run() method of ConnectionInitializer is executed before that of DataInitializer bean.

If no @Order annotation is provided, then the run() methods will be executed in the order the beans are found in the application context.

Conclusion
In this article, we learned how to use spring boot CommandLineRunner interface to execute custom code during application startup.