Spring Boot Property Loading – Logical Overview
Spring Boot provides a flexible property loading mechanism, allowing configuration from multiple sources. It follows a structured process where properties are loaded, merged, and overridden based on precedence rules. Understanding this process helps in debugging and controlling application behavior dynamically.
1. How Spring Boot Loads Properties
Spring Boot follows a structured sequence to load and apply properties, ensuring that the most relevant configurations take precedence.
Step-by-Step Property Loading Process
1️⃣ Initialize Environment (StandardEnvironment
)
- Spring Boot sets up
ConfigurableEnvironment
, which acts as a container for all configuration sources. - This environment is created before beans, ensuring that properties are available throughout the application lifecycle.
2️⃣ Load Property Sources
- Reads System properties (
System.getProperties()
). - Reads Environment variables (
System.getenv()
). - Loads Config files (
application.properties
/.yml
) viaConfigFileApplicationListener
. - Loads Config Server properties if using Spring Cloud Config.
- Reads Custom property sources, such as database-stored configurations or external APIs.
3️⃣ Merge & Apply Property Precedence
- Properties from different sources are merged, and higher-precedence sources override lower ones:
- Command-line arguments > System properties > Environment variables > Config files > Default values
This approach ensures that configuration can be dynamically adjusted at runtime without modifying the application code.
2. System Properties & Environment Variables in Spring Boot
️ Using System.getProperties()
(Java System Properties)
- These are set via JVM options when running the application:
java <span>-Dserver</span>.port<span>=</span>9090 <span>-jar</span> myapp.jarjava <span>-Dserver</span>.port<span>=</span>9090 <span>-jar</span> myapp.jarjava -Dserver.port=9090 -jar myapp.jar
Enter fullscreen mode Exit fullscreen mode
- Internally, Java stores these properties in a
Properties
object that can be accessed via:
<span>System</span><span>.</span><span>getProperties</span><span>().</span><span>getProperty</span><span>(</span><span>"server.port"</span><span>);</span><span>System</span><span>.</span><span>getProperties</span><span>().</span><span>getProperty</span><span>(</span><span>"server.port"</span><span>);</span>System.getProperties().getProperty("server.port");
Enter fullscreen mode Exit fullscreen mode
- These properties are loaded early in Spring Boot’s startup sequence and override properties from files.
️ Using System.getenv()
(Environment Variables)
- These are set at the OS level:
<span>export </span><span>SERVER_PORT</span><span>=</span>9090<span>export </span><span>SERVER_PORT</span><span>=</span>9090export SERVER_PORT=9090
Enter fullscreen mode Exit fullscreen mode
- Retrieved in Java via:
<span>System</span><span>.</span><span>getenv</span><span>(</span><span>"SERVER_PORT"</span><span>);</span><span>System</span><span>.</span><span>getenv</span><span>(</span><span>"SERVER_PORT"</span><span>);</span>System.getenv("SERVER_PORT");
Enter fullscreen mode Exit fullscreen mode
- Environment variables are global and can be accessed across multiple applications.
Difference Between System.getProperties()
and System.getenv()
Feature | System.getProperties() (JVM) |
System.getenv() (OS) |
---|---|---|
Scope | JVM instance only | OS-wide |
Set By | -Dproperty=value |
export VAR=value (Linux/macOS) or set VAR=value (Windows) |
Accessible In | Current Java process | Any process on the system |
Precedence in Spring Boot | Higher than env vars | Lower than JVM properties |
3. Spring Environment & Property Sources
Spring Boot manages configuration through ConfigurableEnvironment
, which organizes properties from multiple sources.
-
ConfigurableEnvironment
acts as a wrapper around various property sources, ensuring that configurations can be:- Overridden dynamically
- Loaded externally without code changes
- Used consistently across beans and services
Primary Property Sources
Source | Example | Precedence |
---|---|---|
Command-line arguments | --server.port=9090 |
Highest |
System properties (System.getProperties() ) |
-Dserver.port=8081 |
High |
Environment variables (System.getenv() ) |
SERVER_PORT=8082 |
Medium |
Application properties | server.port=8083 in application.properties |
Low |
Default values | @Value("${server.port:8084}") |
Lowest |
By using ConfigurableEnvironment
, Spring Boot ensures that property resolution is handled in a structured and predictable manner.
4. PropertySource Hierarchy (Key Sources)
Spring Boot uses PropertySource
objects to encapsulate different property sources. These sources are loaded in a hierarchical order, allowing flexible configuration management.
What is a PropertySource?
- A PropertySource is an abstraction that wraps property values and makes them accessible in the application context.
- Each configuration source (e.g., system properties, config files) is represented as a separate
PropertySource
inConfigurableEnvironment
.
Common PropertySource Implementations
Property Source | Implementation Class | Retrieves Data From |
---|---|---|
System Properties | SystemPropertiesPropertySource |
System.getProperties() |
Environment Variables | SystemEnvironmentPropertySource |
System.getenv() |
Command-line Arguments | CommandLinePropertySource |
CLI (--server.port=8080 ) |
Configuration Files | ConfigurationPropertySources |
application.properties / .yml |
Random Value | RandomValuePropertySource |
random.int , random.uuid |
Servlet Config | ServletConfigPropertySource |
Servlet-specific properties |
5. Inspecting Property Sources at Runtime
Spring Boot allows developers to inspect loaded property sources using getPropertySources()
, which is useful for debugging and runtime modifications.
- Example:
<span>@Autowired</span><span>private</span> <span>Environment</span> <span>environment</span><span>;</span><span>public</span> <span>void</span> <span>printSources</span><span>()</span> <span>{</span><span>((</span><span>ConfigurableEnvironment</span><span>)</span> <span>environment</span><span>).</span><span>getPropertySources</span><span>()</span><span>.</span><span>forEach</span><span>(</span><span>source</span> <span>-></span> <span>System</span><span>.</span><span>out</span><span>.</span><span>println</span><span>(</span><span>source</span><span>.</span><span>getName</span><span>()));</span><span>}</span><span>@Autowired</span> <span>private</span> <span>Environment</span> <span>environment</span><span>;</span> <span>public</span> <span>void</span> <span>printSources</span><span>()</span> <span>{</span> <span>((</span><span>ConfigurableEnvironment</span><span>)</span> <span>environment</span><span>).</span><span>getPropertySources</span><span>()</span> <span>.</span><span>forEach</span><span>(</span><span>source</span> <span>-></span> <span>System</span><span>.</span><span>out</span><span>.</span><span>println</span><span>(</span><span>source</span><span>.</span><span>getName</span><span>()));</span> <span>}</span>@Autowired private Environment environment; public void printSources() { ((ConfigurableEnvironment) environment).getPropertySources() .forEach(source -> System.out.println(source.getName())); }
Enter fullscreen mode Exit fullscreen mode
(This method only lists existing property sources; it does not load new ones.)
This method helps developers verify the source of a property and understand how configurations are resolved.
6. Property Source Precedence (Highest to Lowest)
Spring Boot resolves properties based on a strict order of precedence, ensuring that the most specific settings override broader defaults.
1️⃣ Command-line arguments (--server.port=8081
)
2️⃣ System properties (-Dserver.port=8082
)
3️⃣ Environment variables (SERVER_PORT=8083
)
4️⃣ Config files (application.properties
/ .yml
)
5️⃣ Code defaults (@Value("${server.port:8084}")
)
This hierarchy ensures that temporary configurations (e.g., CLI arguments) take precedence while allowing fallback to default values.
Key Takeaways
Spring Boot merges all property sources before startup, ensuring flexible and externalized configuration.
Higher precedence sources override lower ones, allowing dynamic runtime overrides.
Command-line arguments always take priority, making them ideal for temporary configurations.
Use Environment
API (getProperty()
, getPropertySources()
) to inspect and debug loaded properties.
Happy Coding!
原文链接:spring-015: spring-boot-property-loading–logical-overview
暂无评论内容