Spring Boot binds an effective configuration value after applying property-source precedence; validation must inspect that selected value before serving requests.
Spring Boot property override: fail startup on the effective value
The Spring source kit uses Java 21 and its pinned Spring Boot dependencies. Run the named JUnit test to check this boundary.
Test the actual override
The context runner supplies a default timeout and then a higher-priority test value. A bound @ConfigurationProperties bean sees the selected value, not an unordered collection of both strings. The source kit test checks the effective 12-second timeout.
The second test passes an invalid selected value and expects context startup to fail. This is stronger than checking a private constructor in isolation: the binding and validation path is part of the contract. Binding and validation provides the base rules.
Precedence and secrecy are separate
A value being selected does not make it safe. Bound durations still need range checks; secrets need protected transport, storage and logging policy. This fixture uses a harmless timeout. Java Properties illustrates a manual merge, whereas this page checks Boot's binding path.
Checked contract
@ConfigurationProperties("import") @Validated
public record ImportSettings(@Min(1) @Max(60) int timeoutSeconds) {}
new ApplicationContextRunner()
.withUserConfiguration(SettingsConfig.class)
.withInitializer(context -> {
var sources = context.getEnvironment().getPropertySources();
sources.addLast(new MapPropertySource("packaged-defaults", Map.of("import.timeout-seconds", "8")));
sources.addFirst(new MapPropertySource("operator-overrides", Map.of("import.timeout-seconds", "12")));
})
.run(context -> assertEquals(12,
context.getBean(ImportSettings.class).timeoutSeconds()));How it is checked
ConfigurationOverrideBoundaryTest.selectsAndValidatesTheEffectiveTimeout covers this behavior in the source kit. The displayed code is the test boundary; the kit contains its imports and configuration.
Costs and boundaries
Binding happens during context creation, before request handling. This test covers a selected local property pair, not every external file, environment mapping, command-line source or production secret store.
Common Mistakes
- Do not assume two sources have equal priority when order matters.
- Do not accept a parsed value without validating its operational range.
- Do not expose effective secrets in an error page or actuator output.
Read next
Spring Boot configuration properties: bind values and reject bad startup input, Spring Boot profiles and property precedence: test the selected environment, Spring ApplicationContextRunner: check conditional assembly in isolation, Java Properties precedence: merge sources deliberately.
Continue with checked settings and schema rollout
Continue with Spring Boot command-line properties: test the effective value at startup, Spring Boot configuration sources: test each deployment path, not a guessed order.
