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 -Dserver.port=9090 -jar myapp.jar
- Internally, Java stores these properties in a
Properties
object that can be accessed via:
System.getProperties().getProperty("server.port");
- 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:
export SERVER_PORT=9090
- Retrieved in Java via:
System.getenv("SERVER_PORT");
- 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:
@Autowired
private Environment environment;
public void printSources() {
((ConfigurableEnvironment) environment).getPropertySources()
.forEach(source -> System.out.println(source.getName()));
}
(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! 🚀
Top comments (0)