skip to content

Property sources & precedence

Boot reads properties from files, command-line arguments, environment variables and SPRING_APPLICATION_JSON in a documented order, with the later source winning. Interviewers ask which wins because that ordering is how every deployment overrides a default.

part ofSpring Frameworkoverview, primer and where to startread it →
on this pageshow

questions

5

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?

level: juniorimportance: must knowfreq 70%

answer

  1. Ordered list of PropertySource
  2. First match wins (override, not merge)
  3. CLI args near the top
  4. 'Later in docs' = higher priority
  5. --key=value only

basics

~10 s

The 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 s

The 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
java
// 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

for a junior

Must know the practical rule: command-line args override application.properties; 'later/higher-priority source wins'.

for a middle

Should articulate the ordered PropertySource list and first-match-wins semantics, and distinguish --arg from -D system properties.

for a senior

Should place command-line args precisely in the documented order and know how to disable CLI property parsing.

for a principal

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

context

open as a page

Where does Spring Boot look for application.properties/application.yml by default, in what order, and how do profile-specific files fit in?

level: middleimportance: must knowfreq 65%

basics

~10 s

By default Spring Boot searches four locations: classpath root, classpath /config, the current working directory, and a ./config folder. Locations outside the jar override packaged ones, and profile-specific files (application-{profile}.properties) override the plain file.

open as a page

How do OS environment variables map to Spring property names (relaxed binding), and what is SPRING_APPLICATION_JSON used for?

level: middleimportance: should knowfreq 50%

basics

~20 s

Because shells only allow uppercase letters, digits, and underscores, Spring Boot uses 'relaxed binding': an env var like SPRING_DATASOURCE_URL maps to spring.datasource.url (dots become underscores, uppercased). SPRING_APPLICATION_JSON lets you inject many properties at once as a single JSON string.

open as a page

Walk through Spring Boot's documented property-source precedence order from lowest to highest priority. Where do config files, OS env vars, SPRING_APPLICATION_JSON, and command-line args sit?

level: seniorimportance: should knowfreq 55%

basics

~20 s

Roughly, from lowest to highest: framework defaults, then application.properties/yml config files, then OS environment variables, then Java system properties, then SPRING_APPLICATION_JSON, then command-line arguments, then test overrides. Higher sources override lower ones for the same key.

open as a page

You own the config strategy for a service deployed to dev/staging/prod containers. How do you use Spring Boot's property sources and precedence to layer defaults, per-environment overrides, and secrets safely?

level: principalimportance: should knowfreq 35%

basics

~20 s

Ship one immutable jar with safe defaults in application.yml, add profile-specific files for structural per-environment differences, and override the rest at runtime with environment variables (which outrank the files). Inject secrets from a secrets manager, never bake them into packaged files.

open as a page