Learnitweb

Role of CommandLineRunner & ApplicationRunner in Spring Boot

1. Introduction

When a Spring Boot application starts, it goes through several internal phases:

  • Initializes the Spring context
  • Creates and wires all beans
  • Configures embedded servers (like Tomcat)
  • Loads environment properties
  • Then finally, the application is ready to run

Sometimes, you may want to run specific code immediately after the Spring Boot application has started — for example:

  • Loading initial data into a database
  • Running validation checks
  • Sending startup logs
  • Triggering a background process

To handle such cases, Spring Boot provides two functional interfaces:

  1. CommandLineRunner
  2. ApplicationRunner

Both are part of the org.springframework.boot package and are commonly used to execute code after the application context is loaded but before the application is fully up.

2. CommandLineRunner Overview

2.1 Definition

CommandLineRunner is a functional interface provided by Spring Boot. It allows you to execute code just after the Spring application context is fully initialized.

It is defined as:

@FunctionalInterface
public interface CommandLineRunner {
    void run(String... args) throws Exception;
}

This interface contains a single method:

void run(String... args);

The args parameter represents the command-line arguments passed to the application (from SpringApplication.run()).

2.2 How It Works

  • Spring Boot automatically detects any bean that implements CommandLineRunner.
  • After all beans are created and the context is ready, Spring calls the run() method of those beans.
  • You can define multiple CommandLineRunner beans, and Spring executes them in the order specified by the @Order annotation.

2.3 Example of CommandLineRunner

Step 1: Create a simple Spring Boot application:

@SpringBootApplication
public class MyApplication {
    public static void main(String[] args) {
        SpringApplication.run(MyApplication.class, args);
    }
}

Step 2: Implement CommandLineRunner:

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

@Component
public class StartupRunner implements CommandLineRunner {

    @Override
    public void run(String... args) throws Exception {
        System.out.println("CommandLineRunner executed after Spring Boot startup!");
        for (String arg : args) {
            System.out.println("Argument: " + arg);
        }
    }
}

Step 3: Run the application:

java -jar myapp.jar arg1 arg2

Output:

CommandLineRunner executed after Spring Boot startup!
Argument: arg1
Argument: arg2

3. ApplicationRunner Overview

3.1 Definition

ApplicationRunner is another functional interface similar to CommandLineRunner, introduced to make argument handling more structured and readable.

It is defined as:

@FunctionalInterface
public interface ApplicationRunner {
    void run(ApplicationArguments args) throws Exception;
}

Here, instead of receiving a simple array of String, it uses an ApplicationArguments object that provides:

  • Access to raw arguments
  • Access to option names and their values

This makes it more flexible for handling command-line parameters.

3.2 How It Works

  • Like CommandLineRunner, Spring automatically calls the run() method after the application context is loaded.
  • It gives access to both non-option arguments and option arguments.

Option arguments: arguments that start with --, e.g. --file=data.csv
Non-option arguments: plain arguments like data.csv or input.json

3.3 Example of ApplicationRunner

Step 1: Create a Spring Boot application (same as before).

Step 2: Implement ApplicationRunner:

import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;

@Component
public class AppStartupRunner implements ApplicationRunner {

    @Override
    public void run(ApplicationArguments args) throws Exception {
        System.out.println("ApplicationRunner executed after Spring Boot startup!");

        System.out.println("Non-option args: " + args.getNonOptionArgs());
        System.out.println("Option names: " + args.getOptionNames());

        if (args.containsOption("file")) {
            System.out.println("File option value: " + args.getOptionValues("file"));
        }
    }
}

Step 3: Run the application with parameters:

java -jar myapp.jar --file=data.csv input.txt

Output:

ApplicationRunner executed after Spring Boot startup!
Non-option args: [input.txt]
Option names: [file]
File option value: [data.csv]

4. Execution Order

You can define multiple runners in your application.

Spring Boot executes all CommandLineRunner and ApplicationRunner beans after the context is loaded, but the order depends on the @Order annotation or by implementing the Ordered interface.

Example:

@Component
@Order(1)
public class FirstRunner implements CommandLineRunner {
    public void run(String... args) {
        System.out.println("First Runner");
    }
}

@Component
@Order(2)
public class SecondRunner implements CommandLineRunner {
    public void run(String... args) {
        System.out.println("Second Runner");
    }
}

Output:

First Runner
Second Runner

5. Differences Between CommandLineRunner and ApplicationRunner

FeatureCommandLineRunnerApplicationRunner
Method Signaturevoid run(String... args)void run(ApplicationArguments args)
Argument TypeArray of StringsApplicationArguments object
Argument HandlingSimple; manual parsingStructured; supports options and non-options
Best Use CaseQuick or simple startup tasksWhen you need detailed access to command-line arguments
FlexibilityBasicMore advanced and readable
AvailabilitySince Spring Boot 1.0Introduced in Spring Boot 1.3

Both interfaces are executed after the Spring container is fully initialized.

6. Use Cases

Here are some common real-world use cases for both interfaces:

  1. Database Initialization
    • Load default records or seed data when the application starts.
    • Example: populating lookup tables with default values.
  2. Configuration Validation
    • Verify that required environment variables or configuration files exist before the app continues.
  3. Background Job Trigger
    • Start a scheduler, async task, or message listener after context initialization.
  4. Startup Logging
    • Print diagnostic information, such as active profiles or environment settings.
  5. Data Migration
    • Run scripts or perform small transformations during version upgrades.
  6. Integration Testing
    • Trigger pre-test setup tasks during test startup.

7. Combining Both in a Single Application

It’s possible to use both interfaces together in the same Spring Boot app.
They execute independently but after the application context is ready.

Example:

@Component
public class CombinedRunner implements CommandLineRunner, ApplicationRunner {

    @Override
    public void run(String... args) throws Exception {
        System.out.println("CommandLineRunner executed");
    }

    @Override
    public void run(ApplicationArguments args) throws Exception {
        System.out.println("ApplicationRunner executed");
    }
}

Output:

ApplicationRunner executed
CommandLineRunner executed

(Order may vary depending on internal execution and bean ordering.)

8. Best Practices

  1. Keep Runners Lightweight
    • Avoid long-running tasks in run() methods; use separate threads or schedulers for heavy operations.
  2. Use @Order
    • Always specify the order when multiple runners are present for predictable execution.
  3. Prefer ApplicationRunner for Argument Parsing
    • It provides a cleaner API for working with arguments.
  4. Avoid Blocking the Main Thread
    • If your runner starts background jobs, consider running them asynchronously.
  5. Use Profiles for Conditional Execution
    • Combine runners with @Profile to execute startup logic only in specific environments (e.g., dev, test, prod).

9. Summary

FeatureCommandLineRunnerApplicationRunner
PurposeRun code after application startupSame, with enhanced argument handling
Argument TypeString arrayApplicationArguments
Ease of UseSimpleMore flexible
Typical UseQuick startup tasksTasks needing argument parsing
Execution TimingAfter context initializationAfter context initialization
OrderingControlled via @OrderControlled via @Order

Both CommandLineRunner and ApplicationRunner are extremely useful for executing custom logic after Spring Boot starts — they are part of the application lifecycle that bridges the gap between context initialization and runtime readiness.


10. Conclusion

  • CommandLineRunner and ApplicationRunner are startup hooks in Spring Boot.
  • Both execute after Spring context initialization, making them ideal for initialization, validation, or data setup tasks.
  • Use ApplicationRunner if you need to handle complex command-line arguments.
  • For most basic use cases, CommandLineRunner is sufficient.

They are simple yet powerful tools to automate startup behavior in a clean, Spring-managed way.