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:
- CommandLineRunner
- 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
CommandLineRunnerbeans, and Spring executes them in the order specified by the@Orderannotation.
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 therun()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
| Feature | CommandLineRunner | ApplicationRunner |
|---|---|---|
| Method Signature | void run(String... args) | void run(ApplicationArguments args) |
| Argument Type | Array of Strings | ApplicationArguments object |
| Argument Handling | Simple; manual parsing | Structured; supports options and non-options |
| Best Use Case | Quick or simple startup tasks | When you need detailed access to command-line arguments |
| Flexibility | Basic | More advanced and readable |
| Availability | Since Spring Boot 1.0 | Introduced 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:
- Database Initialization
- Load default records or seed data when the application starts.
- Example: populating lookup tables with default values.
- Configuration Validation
- Verify that required environment variables or configuration files exist before the app continues.
- Background Job Trigger
- Start a scheduler, async task, or message listener after context initialization.
- Startup Logging
- Print diagnostic information, such as active profiles or environment settings.
- Data Migration
- Run scripts or perform small transformations during version upgrades.
- 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
- Keep Runners Lightweight
- Avoid long-running tasks in
run()methods; use separate threads or schedulers for heavy operations.
- Avoid long-running tasks in
- Use @Order
- Always specify the order when multiple runners are present for predictable execution.
- Prefer ApplicationRunner for Argument Parsing
- It provides a cleaner API for working with arguments.
- Avoid Blocking the Main Thread
- If your runner starts background jobs, consider running them asynchronously.
- Use Profiles for Conditional Execution
- Combine runners with
@Profileto execute startup logic only in specific environments (e.g.,dev,test,prod).
- Combine runners with
9. Summary
| Feature | CommandLineRunner | ApplicationRunner |
|---|---|---|
| Purpose | Run code after application startup | Same, with enhanced argument handling |
| Argument Type | String array | ApplicationArguments |
| Ease of Use | Simple | More flexible |
| Typical Use | Quick startup tasks | Tasks needing argument parsing |
| Execution Timing | After context initialization | After context initialization |
| Ordering | Controlled via @Order | Controlled 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
CommandLineRunnerandApplicationRunnerare 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.
