Enterprise Java

Spring Boot CommandLineRunner and ApplicationRunner

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.

CommandLineRunner:

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:

01
02
03
04
05
06
07
08
09
10
@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));
    }
}

And now, let’s bootstrap our Spring Boot application executable jar:

1
java -jar SampleApp-1.0.jar parameter1 parameter2 parameter3

Along with three command-line arguments: parameter1, parameter2, and parameter3.

Our console logs would then be:

1
2
3
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

Where all the provided arguments got listed.

ApplicationRunner:

Similarly, we can define beans that implement the ApplicationRunner interface:

01
02
03
04
05
06
07
08
09
10
11
@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");
    }
  
}

The ApplicationRunner provides access to the ApplicationArguments, not just the raw String arguments. Rather, technically speaking, that’s the only difference between them.

How many ApplicationRunner & CommandLineRunner Implementations?

We are free to define any number of CommandLineRunner and ApplicationRunner implementations as we need.

Java 8 Definitions:

With Java 8 lambda’s, we can have a code:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
@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()))
    }
}

Which defines the implementation of these interfaces in our Application class itself.

Ordering:

We can also impose ordering on the execution of these beans using the @Order annotation.

Say, we have two CommandLineRunner implementations:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
@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");    
    }
}

Along with a class that implements the ApplicationRunner:

01
02
03
04
05
06
07
08
09
10
@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");
    }
}

Clearly, our CmdRunner1 will get executed first followed by the AppRunner and finally the CmdRunner2.

Conclusion:

In this tutorial, we talked about the CommandLineRunner and ApplicationRunner interfaces provided by Spring Boot.

Published on Java Code Geeks with permission by Shubhra Srivastava, partner at our JCG program. See the original article here: Spring Boot CommandLineRunner and ApplicationRunner

Opinions expressed by Java Code Geeks contributors are their own.

Shubhra Srivastava

Shubhra is a software professional and founder of ProgrammerGirl. She has a great experience with Java/J2EE technologies and frameworks. She loves the amalgam of programming and coffee :)
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Inline Feedbacks
View all comments
Back to top button