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
Propertiesobject 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.
-
ConfigurableEnvironmentacts 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
PropertySourceinConfigurableEnvironment.
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)