Spring Boot CommandLineRunner vs ApplicationRunner

By Arvind Rai, 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.

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) 
We get the arguments as an array of 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);
    }
} 
MyApplication.java
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());
        }       
} 
We are also creating a service. Service will execute once the Spring Boot finishes its startup. It means our service method will run after 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!";
	}
}
Now run the application using executable JAR with arguments. Build the project and suppose we get the JAR with the name spring-boot-demo-0.0.1-SNAPSHOT.jar.
java -jar spring-boot-demo-0.0.1-SNAPSHOT.jar data1 data2 data3 
The output will be as follows.
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) 
We will observe that the 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);
	}
} 
Create executable JAR and run with arguments as follows.
java -jar spring-boot-demo-0.0.1-SNAPSHOT.jar data1 data2 data3 
The output will be as follows.
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 implementing CommandLineRunner 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");
    }
}
ApplicationRunnerBean1.java
@Component
@Order(2)
public class ApplicationRunnerBean1 implements ApplicationRunner {
	@Override
	public void run(ApplicationArguments arg0) throws Exception {
		System.out.println("ApplicationRunnerBean 1");
	}
}
CommandLineRunnerBean2.java
@Component
@Order(3)
public class CommandLineRunnerBean2 implements CommandLineRunner {
    public void run(String... args) {
    	System.out.println("CommandLineRunnerBean 2");
    }
}
ApplicationRunnerBean2.java
@Component
@Order(4)
public class ApplicationRunnerBean2 implements ApplicationRunner {
	@Override
	public void run(ApplicationArguments arg0) throws Exception {
		System.out.println("ApplicationRunnerBean 2");
	}
} 
When we run the application, we will get following output.
CommandLineRunnerBean 1
ApplicationRunnerBean 1
CommandLineRunnerBean 2
ApplicationRunnerBean 2 

Reference

Using the ApplicationRunner or CommandLineRunner
POSTED BY
ARVIND RAI
ARVIND RAI







©2024 concretepage.com | Privacy Policy | Contact Us