Spring Boot
CommandLineRunner
Java
command line arguments
application development

Multiple Spring boot CommandLineRunner based on command line argument

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

Introduction

Running different CommandLineRunner beans based on command-line arguments in Spring Boot is best handled through conditional bean registration. This keeps startup logic explicit and avoids large argument-parsing blocks inside one runner.

Short troubleshooting answers often solve the immediate error but miss maintainability concerns such as reproducibility, observability, and rollback safety. A complete implementation should make assumptions explicit, validate edge cases, and produce diagnostics that are useful during incidents.

When adapting snippets, verify version compatibility, runtime environment, and operational limits before rollout. Small contextual differences, such as framework version, deployment topology, or data shape, can change behavior significantly.

Core Sections

1. Establish a minimal correct solution

Use @ConditionalOnProperty or profile-based conditions to activate specific runners. Then pass arguments as properties when starting the app.

java
1@Component
2@ConditionalOnProperty(name = "job", havingValue = "import")
3public class ImportRunner implements CommandLineRunner {
4    @Override
5    public void run(String... args) {
6        System.out.println("Running import job");
7    }
8}
9
10@Component
11@ConditionalOnProperty(name = "job", havingValue = "cleanup")
12class CleanupRunner implements CommandLineRunner {
13    public void run(String... args) {
14        System.out.println("Running cleanup job");
15    }
16}

This baseline should stay intentionally simple so correctness is easy to verify. Once the minimal behavior is confirmed, extend it with error handling and performance considerations rather than starting with complex abstractions.

2. Harden for production requirements

If one runner must dispatch internally, parse ApplicationArguments and route to strategy components. This preserves testability and keeps runner thin.

java
1@Component
2public class DispatcherRunner implements CommandLineRunner {
3    private final ApplicationArguments args;
4    private final Map<String, Runnable> jobs;
5
6    public DispatcherRunner(ApplicationArguments args, Map<String, Runnable> jobs) {
7        this.args = args;
8        this.jobs = jobs;
9    }
10
11    public void run(String... ignored) {
12        String job = args.getOptionValues("job").get(0);
13        jobs.getOrDefault(job, () -> { throw new IllegalArgumentException("unknown job"); }).run();
14    }
15}

Production hardening usually includes explicit validation, clear failure semantics, and safe resource lifecycle management. It also helps to centralize configuration and shared logic so behavior remains consistent across environments and teams.

3. Validate and operate with confidence

Ensure only one startup path executes per run unless multi-job behavior is intentional. Add integration tests for each command variant and document invocation examples for operators.

Add a practical verification loop with one happy-path test, one edge-case test, and one failure-path test. Pair tests with lightweight runtime signals such as error rates, latency percentiles, or startup checks so regressions are detected early.

Operational readiness includes rollback planning. Even correct code may fail under unexpected dependencies or data. Documenting rollback steps and fallback behavior reduces recovery time and deployment risk.

Implementation depth also includes long-term operability. Define clear ownership of configuration, data contracts, and failure handling so support engineers can diagnose issues without reverse engineering intent from old commits. Where possible, capture representative input and output examples in tests, because executable examples age better than prose-only documentation.

For production systems, add lightweight observability close to the critical path: structured logs for key decisions, counters for failure categories, and latency metrics around expensive operations. These signals should map to user impact directly so on-call responders can prioritize correctly under pressure. Strong observability turns debugging from guesswork into a bounded investigation.

Finally, prepare rollback and fallback behavior before deploying significant changes. Even technically correct updates can fail due to environment differences, data anomalies, or dependency upgrades. A preplanned rollback path, feature flag, or degraded-mode strategy reduces mean time to recovery and allows teams to iterate quickly without risking prolonged outages.

Common Pitfalls

  • Registering multiple runners without conditions and running all unintentionally.
  • Parsing command-line arguments manually without validation.
  • Failing silently when unknown job names are provided.
  • Mixing job dispatch and business logic in one oversized runner class.
  • Skipping tests for startup argument permutations.

Summary

Use conditional runner beans or a thin dispatcher pattern to select startup jobs based on arguments. Explicit activation and validation make command-driven Spring Boot apps predictable and maintainable. Pair implementation detail with testing and operational safeguards so the solution remains reliable as code, dependencies, and infrastructure evolve.


Related reading
Course
Intermediate
27 lessons
14 hours
OOD Fundamentals

Master object-oriented design from first principles, SOLID, design patterns, and classic interview problems with hands-on coding.

View the course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

All Rights Reserved.