Spring Boot CommandLineRunner vs ApplicationRunner
December 07, 2023
In Spring Boot application, we can execute any task just before Spring Boot finishes its startup. To do so we need to create Spring bean using CommandLineRunner
or ApplicationRunner
interface and Spring Boot will automatically detect them. Both the interfaces have run()
method that needs to be overridden in implementing class and make the class as bean by using Spring stereotype such as @Component
. CommandLineRunner
and ApplicationRunner
serve the same purpose. The difference between CommandLineRunner
and ApplicationRunner
is that the run()
method of CommandLineRunner
accepts array of String
as an argument and run()
method of ApplicationRunner
accepts Spring ApplicationArguments
as an argument. The arguments which we pass to main()
method while starting Spring boot, can be accessed in the run()
method of CommandLineRunner
and ApplicationRunner
implementation classes. We can create more than one bean of CommandLineRunner
and ApplicationRunner
implementing classes. To execute them in an order, we use Spring @Order
annotation or Ordered
interface.
The
run()
method of CommandLineRunner
and ApplicationRunner
are executed just before SpringApplication
finishes its startup. After startup completes, application starts to run. The usability of CommandLineRunner
and ApplicationRunner
are that we can start any scheduler or log any message before application starts to run. Now let us discuss the example how to use CommandLineRunner
and ApplicationRunner
in our application.
Contents
Maven File
Find the maven file used in our example.pom.xml
<?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.concretepage</groupId> <artifactId>spring-boot-demo</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>spring-demo</name> <description>Spring Boot Demo Project</description> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.2.RELEASE</version> </parent> <properties> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
CommandLineRunner
CommandLineRunner
is an interface that has a method as run( )
. To use CommandLineRunner
we will create a class and implement it and override its run()
method. Now annotate this class with Spring stereotype such as @Component
. When the SpringApplication.run()
starts the Spring Boot application then just before finishing startup, CommandLineRunner.run()
will be executed. The run()
method of CommandLineRunner
accepts the arguments that are passed while starting server. Find the method.
run(String... args)
String
. Now find the example.
CommandLineRunnerBean.java
package com.concretepage.bean; import java.util.Arrays; import java.util.stream.Collectors; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.boot.CommandLineRunner; import org.springframework.stereotype.Component; @Component public class CommandLineRunnerBean implements CommandLineRunner { private static final Logger logger = LoggerFactory.getLogger(CommandLineRunnerBean.class); public void run(String... args) { String strArgs = Arrays.stream(args).collect(Collectors.joining("|")); logger.info("Application started with arguments:" + strArgs); } }
package com.concretepage; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.ConfigurableApplicationContext; import com.concretepage.service.HelloService; @SpringBootApplication public class MyApplication { private static final Logger logger = LoggerFactory.getLogger(MyApplication.class); public static void main(String[] args) { ConfigurableApplicationContext context = SpringApplication.run(MyApplication.class, args); HelloService service = context.getBean(HelloService.class); logger.info(service.getMessage()); } }
SpringApplication.run()
completes its execution. Find the service used in our example.
HelloService.java
package com.concretepage.service; import org.springframework.stereotype.Service; @Service public class HelloService { public String getMessage(){ return "Hello World!"; } }
java -jar spring-boot-demo-0.0.1-SNAPSHOT.jar data1 data2 data3
2017-03-19 13:38:38.909 INFO 1036 --- [ main] c.c.bean.CommandLineRunnerBean : Application started with arguments:data1|data2|data3 2017-03-19 13:38:38.914 INFO 1036 --- [ main] com.concretepage.MyApplication : Started MyApplication in 1.398 seconds (JVM running for 1.82) 2017-03-19 13:38:38.915 INFO 1036 --- [ main] com.concretepage.MyApplication : Hello World!
ApplicationRunner
ApplicationRunner
serves the same purpose as CommandLineRunner
. The run()
method of ApplicationRunner
is executed just before SpringApplication.run()
finishes Spring Boot startup. Find the run()
method signature of ApplicationRunner
.
run(ApplicationArguments args)
CommandLineRunner.run()
accepts array of String
and ApplicationRunner.run()
accepts ApplicationArguments
as an argument. These arguments are those arguments that are passed to main()
method while starting Spring Boot application. Find the example.
ApplicationRunnerBean.java
package com.concretepage.bean; import java.util.Arrays; import java.util.stream.Collectors; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.boot.ApplicationArguments; import org.springframework.boot.ApplicationRunner; import org.springframework.stereotype.Component; @Component public class ApplicationRunnerBean implements ApplicationRunner { private static final Logger logger = LoggerFactory.getLogger(ApplicationRunnerBean.class); @Override public void run(ApplicationArguments arg0) throws Exception { String strArgs = Arrays.stream(arg0.getSourceArgs()).collect(Collectors.joining("|")); logger.info("Application started with arguments:" + strArgs); } }
java -jar spring-boot-demo-0.0.1-SNAPSHOT.jar data1 data2 data3
2017-03-19 16:26:06.952 INFO 5004 --- [ main] c.c.bean.ApplicationRunnerBean : Application started with arguments:data1|data2|data3 2017-03-19 16:26:06.956 INFO 5004 --- [ main] com.concretepage.MyApplication : Started MyApplication in 1.334 seconds (JVM running for 1.797) 2017-03-19 16:26:06.957 INFO 5004 --- [ main] com.concretepage.MyApplication : Hello World!
Order of CommandLineRunner and ApplicationRunner
In our Spring Boot application we can use more than one bean that are implementingCommandLineRunner
and ApplicationRunner
. To execute the run()
methods of these bean in an order, we can use @Order
annotation or Ordered
interface. In our example we have created two bean implementing CommandLineRunner
interface and two bean implementing ApplicationRunner
interface. To execute these four beans in an order we are using @Order
annotation. Find the example.
CommandLineRunnerBean1.java
@Component @Order(1) public class CommandLineRunnerBean1 implements CommandLineRunner { public void run(String... args) { System.out.println("CommandLineRunnerBean 1"); } }
@Component @Order(2) public class ApplicationRunnerBean1 implements ApplicationRunner { @Override public void run(ApplicationArguments arg0) throws Exception { System.out.println("ApplicationRunnerBean 1"); } }
@Component @Order(3) public class CommandLineRunnerBean2 implements CommandLineRunner { public void run(String... args) { System.out.println("CommandLineRunnerBean 2"); } }
@Component @Order(4) public class ApplicationRunnerBean2 implements ApplicationRunner { @Override public void run(ApplicationArguments arg0) throws Exception { System.out.println("ApplicationRunnerBean 2"); } }
CommandLineRunnerBean 1 ApplicationRunnerBean 1 CommandLineRunnerBean 2 ApplicationRunnerBean 2