In Spring Boot, sometimes you want to run some code right after the application startsβsuch as initializing data, setting up caches, or calling external services.
Spring Boot provides two interfaces for this:
CommandLineRunner
ApplicationRunner
Both are functional interfaces that let you execute logic after the SpringApplication.run(...)
method is complete.

π§ Why Use CommandLineRunner and ApplicationRunner in Spring Boot?
Here are common use cases:
- Seeding a database
- Running background tasks
- Verifying configuration
- Logging app metadata at startup
- Connecting to external services (Kafka, Redis, etc.)
π οΈ 1. Using CommandLineRunner
π¦ Interface:
1 2 3 4 5 6 |
@FunctionalInterface public interface CommandLineRunner { void run(String... args) throws Exception; } |
β Example:
1 2 3 4 5 6 7 8 9 10 11 12 |
@Component public class MyCommandLineRunner implements CommandLineRunner { @Override public void run(String... args) { System.out.println("CommandLineRunner: App just started!"); for (String arg : args) { System.out.println("Arg: " + arg); } } } |
This code will run once after the app starts and prints the command-line arguments.
π οΈ 2. Using ApplicationRunner
π¦ Interface:
1 2 3 4 5 6 |
@FunctionalInterface public interface ApplicationRunner { void run(ApplicationArguments args) throws Exception; } |
β Example:
1 2 3 4 5 6 7 8 9 10 11 12 |
@Component public class MyApplicationRunner implements ApplicationRunner { @Override public void run(ApplicationArguments args) { System.out.println("ApplicationRunner: App has started!"); if (args.containsOption("user")) { System.out.println("User arg: " + args.getOptionValues("user")); } } } |
You can start your app like this:
1 2 3 4 |
java -jar app.jar --user=admin |
And get output like:
1 2 3 4 |
User arg: [admin] |
π Key Differences
Feature | CommandLineRunner | ApplicationRunner |
---|---|---|
Argument Type | Simple String[] | ApplicationArguments object |
Argument Parsing | Manual | Structured parsing available |
Best For | Simple, quick start-up logic | When argument parsing is needed |
Input | Raw values | Named/option args via --key=value |
Both are called after the Spring ApplicationContext is fully initialized.
π‘ Using Lambda Style (Java 8+)
You can also define runners using lambda syntax inside your main class:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
@SpringBootApplication public class DemoApp { public static void main(String[] args) { SpringApplication.run(DemoApp.class, args); } @Bean CommandLineRunner clr() { return args -> { System.out.println("CLR inside @Bean"); }; } @Bean ApplicationRunner ar() { return args -> { System.out.println("AR inside @Bean"); }; } } |
π§ͺ Real-World Use Case: Seeding a Database
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
@Component public class DataSeeder implements CommandLineRunner { private final UserRepository userRepository; public DataSeeder(UserRepository userRepository) { this.userRepository = userRepository; } @Override public void run(String... args) { userRepository.save(new User("admin", "admin@example.com")); System.out.println("Initial user created"); } } |
β Best Practices
Tip | Why |
---|---|
Use @Component or @Bean | For automatic registration |
Use ApplicationRunner for structured args | Easier command-line parsing |
Avoid heavy operations | Startup code should be quick |
Use @Order if you need ordering | Control the execution sequence of runners |
Log errors properly | Avoid crashing the app on startup |
π§ Ordering Multiple Runners
If you have multiple runners and want to control their execution order:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
@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"); } } |
π§ Optional: Conditional Execution
You can conditionally enable or disable a runner using @ConditionalOnProperty
, @Profile
, or environment checks.
1 2 3 4 5 6 |
@Component @ConditionalOnProperty(name = "app.seed-data", havingValue = "true") public class DataSeeder implements CommandLineRunner { // ... } |
Enable via:
1 2 3 |
app.seed-data=true |
β Summary
Concept | Details |
---|---|
CommandLineRunner | Runs code after app startup using String[] args |
ApplicationRunner | Runs code with structured ApplicationArguments |
Registering runners | Use @Component or define as @Bean |
Use cases | DB seeding, background tasks, config check |
Both CommandLineRunner and ApplicationRunner in Spring Boot are excellent tools for running logic after the Spring app has initialized β quick, elegant, and built right into the framework.