In this quick tutorial, we’ll explore the two very popular interfaces in Spring Boot: CommandLineRunner and ApplicationRunner.
One common use case of these interfaces is to load some static data at application startup. Though, I have seen such usages mostly for test data setup only.
Both of them are functional interfaces with a run() method. This run() method gets executed soon after the ApplicationContext is loaded and before SpringApplication#run method execution ends.
We have access to the application arguments as a raw String in the CommandLineRunner’s run() method.
Let’s see that with the help of an example.
Firstly, let’s write a bean that implements the CommandLineRunner interface:
@Component public class SampleCmdRunner implements CommandLineRunner { private static final Logger LOG = LoggerFactory.getLogger(SampleCmdRunner.class); @Override public void run(String[] args) { LOG.info("Executing the command line runner, Application arguments: " + Arrays.toString(args)); } }
java -jar SampleApp-1.0.jar parameter1 parameter2 parameter3
Our console logs would then be:
s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat started on port(s): 8080 (http) Executing the command line runner, Application arguments: [parameter1, parameter2, parameter3] 2019-09-02 11:02:10.111 INFO 7676 --- [main] com.programmergirl.SampleApp : Started SampleApp in 2.11 seconds
Similarly, we can define beans that implement the ApplicationRunner interface:
@Component public class SampleAppRunner implements ApplicationRunner { private static final Logger LOG = LoggerFactory.getLogger(SampleAppRunner.class); @Override public void run(ApplicationArguments args) { LOG.info("Executing SampleAppRunner"); } }
We are free to define any number of CommandLineRunner and ApplicationRunner implementations as we need.
With Java 8 lambda’s, we can have a code:
@SpringBootApplication public class SampleApp { public static void main(String[] args) { SpringApplication.run(SampleApp.class, args); } @Bean CommandLineRunner commandLineRunner() { return args -> System.out.println("CommandLineRunner with args:" + Arrays.toString(args)); } @Bean ApplicationRunner applicationRunner() { return args -> System.out.println("ApplicationRunner with args:" + Arrays.toString(args.getSourceArgs())) } }
We can also impose ordering on the execution of these beans using the @Order annotation.
Say, we have two CommandLineRunner implementations:
@Component @Order(1) public class CmdRunner1 implements CommandLineRunner { private static final Logger LOG = LoggerFactory.getLogger(CmdRunner1.class); @Override public void run(String[] args) { LOG.info("In CmdRunner1"); } } @Component @Order(3) public class CmdRunner2 implements CommandLineRunner { private static final Logger LOG = LoggerFactory.getLogger(CmdRunner2.class); @Override public void run(String[] args) { LOG.info("In CmdRunner2"); } }
@Component @Order(2) public class AppRunner implements ApplicationRunner { private static final Logger LOG = LoggerFactory.getLogger(AppRunner.class); @Override public void run(ApplicationArguments args) { LOG.info("In AppRunner"); } }
In this tutorial, we talked about the CommandLineRunner and ApplicationRunner interfaces provided by Spring Boot.