In Spring Boot, if the same property (say server.port) is set in application.properties AND passed as a command-line argument, which value wins and why?
answer
- Ordered list of PropertySource
- First match wins (override, not merge)
- CLI args near the top
- 'Later in docs' = higher priority
- --key=value only
basics
~10 sThe command-line argument wins. Spring Boot reads config from many places (property sources). When a key exists in several, the higher-priority source overrides the others, and command-line arguments outrank application.properties.
solid answer
~40 sThe command-line argument wins. Spring Boot builds an Environment from an ordered list of PropertySource objects. When you ask for a property, it walks that list and returns the first match, so the highest-priority source effectively overrides lower ones. Command-line arguments (parsed into a CommandLinePropertySource) sit near the top of the order, well above the application.properties/yaml files (the 'config data' source). So `--server.port=9090` overrides `server.port=8080` in application.properties. This is the whole point of externalized configuration: you bake sensible defaults into the packaged app and override them per environment at launch (CLI args, environment variables, etc.) without rebuilding the jar. The common shorthand is 'later sources win' — where 'later' means later in Spring Boot's documented precedence list, not chronological order.
code
java · 21 lines// application.properties (packaged in the jar):
// server.port=8080
// Launch overriding it from the command line:
// java -jar app.jar --server.port=9090
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Component;
@Component
class PortReporter {
@Value("${server.port}")
int port; // == 9090 when launched with --server.port=9090
PortReporter(Environment env) {
// Same result via the Environment API:
System.out.println(env.getProperty("server.port")); // "9090"
}
}go deeper
Must know the practical rule: command-line args override application.properties; 'later/higher-priority source wins'.
Should articulate the ordered PropertySource list and first-match-wins semantics, and distinguish --arg from -D system properties.
Should place command-line args precisely in the documented order and know how to disable CLI property parsing.
Frames this as the externalized-configuration contract enabling one immutable artifact reconfigured per environment.
## The core idea Spring Boot does not read configuration from a single file. At startup it assembles a `org.springframework.core.env.Environment` that holds an **ordered list of `PropertySource` objects**. Each `PropertySource` is just a named bag of key/value pairs (one for command-line args, one for OS environment variables, one for your `application.properties`, and so on). When code asks for a value — via `@Value("${server.port}")`, `environment.getProperty("server.port")`, or `@ConfigurationProperties` binding — Spring **walks the list in order and returns the first source that contains the key**. Because higher-priority sources are consulted first, they *override* the same key defined in lower-priority sources. Nothing is merged or added together; the first hit wins. ## Why the command-line argument beats application.properties Command-line arguments are captured in a `CommandLinePropertySource` (specifically `SimpleCommandLinePropertySource`) that Spring Boot places **near the top** of the precedence list. Your `application.properties` / `application.yml` files become a lower-priority source (the 'Config Data' source). Since the command-line source is consulted first, `--server.port=9090` shadows `server.port=8080` in the file. ## 'Later wins' — what 'later' means The Spring Boot reference documents the property sources in a fixed order. The convention in the docs is that **items listed later have higher priority** (they override earlier ones). So 'later' refers to position in that documented list, not to when a value was written. A rough top-down view (highest priority first): test overrides, then command-line arguments, then `SPRING_APPLICATION_JSON`, then Java system properties, then OS environment variables, then the `application.properties`/`yaml` config data files, then defaults. ## Command-line argument syntax Spring Boot recognizes options of the form `--name=value` (two leading dashes). Example: `java -jar app.jar --server.port=9090 --spring.profiles.active=prod`. Non-option arguments (no `--`) are collected separately and are **not** treated as properties. ## Gotchas - **Only `--key=value` becomes a property.** `-Dserver.port=9090` is a JVM system property (also high priority, but a *different* source), while `server.port=9090` placed after `-jar app.jar` without dashes is a plain program argument, not a property. - You can disable command-line property parsing with `SpringApplication.setAddCommandLineProperties(false)` — then CLI args stop overriding files (rarely needed, but asked about). - 'Wins' means override, not accumulate: if the key is absent from the higher source, Spring falls through to the next source. ## When this matters This layering is how you ship one immutable artifact and reconfigure it per environment (dev/staging/prod) purely from the outside — CLI flags in a script, environment variables in a container, etc. — without editing the packaged file.
- Does '--server.port=9090' behave the same as '-Dserver.port=9090'?Both override the file, but they are different sources. `--server.port=9090` (after the jar) becomes a command-line property source; `-Dserver.port=9090` (before -jar) is a JVM system property source. Both outrank application.properties, and command-line args outrank system properties.
- If a key is NOT in the command-line args, where does Spring look next?It falls through the ordered list to the next source — system properties, then OS environment variables, then the application.properties/yaml config data — returning the first source that has the key. Override only happens when the higher source actually contains the key.
saying these in an interview costs you the question
- Claiming application.properties always wins because it's 'the config file'
- Thinking values from different sources are merged/summed rather than overridden by first match
- Believing 'later wins' means the last file edited or the last line in a file
- Assuming any program argument (without --) becomes a property