DEV Community

Hunor Vadasz-Perhat
Hunor Vadasz-Perhat

Posted on

spring-015: spring-boot-property-loading–logical-overview

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) via ConfigFileApplicationListener.
  • 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
Enter fullscreen mode Exit fullscreen mode
  • Internally, Java stores these properties in a Properties object that can be accessed via:
  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:
  export SERVER_PORT=9090
Enter fullscreen mode Exit fullscreen mode
  • Retrieved in Java via:
  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 in ConfigurableEnvironment.

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()));
  }
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! 🚀

Top comments (0)