Skip to main content

Welcome to a Grasp lesson

Create a free account to keep studying and create your own study path.

Lesson 16

Configuring Application Properties

Recommended resources

Introduction

Welcome to the next lesson in our exploration of Spring Boot. In our previous lesson, we saw how Spring Boot starters dramatically simplify dependency management, and how they work with auto-configuration to automatically set up your application with sensible defaults. This is powerful, but in any real-world system, from a simple web app to a complex microservices architecture, you need to control and customize this behavior. You need to tell your application which database to connect to, what port to run on, or where to find an external API.

This lesson directly addresses that need. We will cover how to configure your application using application.properties and application.yml files. This practice of externalizing configuration is a cornerstone of modern application development, famously codified as the third factor in the 12-Factor App methodology. For someone with your background in system design, the importance of separating configuration from code will be very familiar. Here, you'll learn the specific mechanisms Spring Boot provides to achieve this elegantly.


The Basics: application.properties vs application.yml

When you generate a Spring Boot project, it includes an empty file in src/main/resources called application.properties. This is the primary location for your application's configuration. Spring Boot automatically loads this file at startup and uses it to configure the beans created by the auto-configuration process.

You have two primary format choices for this file: the traditional Java .properties format and the more modern .yml (YAML) format.

To get a quick visual comparison of these two formats and understand their core differences, please watch the first part of this video.

application.yml vs application.properties in SpringBoot | Properties vs YAML | Geekific

This video from Geekific provides a concise side-by-side comparison of the application.properties and application.yml formats.

Watch from 00:14 to 00:54 and then from 02:01 to 02:52. The first segment introduces the .properties format, and the second introduces the .yml format and compares them. Focus on how hierarchical data (like spring.datasource) and lists are represented in each.

Now, let's dive into the specifics of each format.

1. application.properties

This file uses a simple key-value pair format, with each property on a new line. It's straightforward and has been a standard in the Java world for a long time.

Application.properties Beginner's Guide
This image shows common examples of properties you might configure in a Spring Boot application, such as the application name, server port, and database connection details.

Hierarchical properties are defined using dot-separated prefixes, for example:




# Server configuration
server.port=8080




# Custom application property
app.greeting=Hello from Properties!




# Database configuration (hierarchical)
spring.datasource.url=jdbc:h2:mem:testdb
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=password

2. application.yml

YAML (YAML Ain't Markup Language) is a data serialization language that is often used for configuration files. Its main advantage is readability, especially for complex, nested configurations. Given your experience with Python, the indentation-based structure will feel natural.

The same configuration as above would look like this in an application.yml file:




# Server configuration
server:
  port: 8080




# Custom application property
app:
  greeting: Hello from YAML!




# Database configuration (hierarchical)
spring:
  datasource:
    url: jdbc:h2:mem:testdb
    driverClassName: org.h2.Driver
    username: sa
    password: password

Notice how the repetitive spring.datasource prefix is gone, making the structure much clearer.

For a more detailed look at the syntax, including how to represent lists and use placeholders, please read the following sections from a Baeldung article, a well-regarded resource in the Java community.

Using application.yml vs application.properties in Spring Boot

This article, 'Using application.yml vs application.properties in Spring Boot', provides excellent examples of the syntax for both file types.

Read 'Section 2. Properties Configuration' and 'Section 3. YAML Configuration'. Pay close attention to how each format handles lists and hierarchical data.

Key Differences and Loading Order

  • Readability: YAML is generally more readable for nested properties.
  • Verbosity: .properties can be more verbose due to repeated prefixes.
  • Lists: YAML has a more natural and concise syntax for lists.
  • Safety: YAML's reliance on indentation can sometimes lead to subtle errors if not handled carefully, whereas .properties is flat and less prone to structural mistakes.

A crucial point to remember is the loading order. If you have both an application.properties and an application.yml file in your project, Spring Boot will load both, but properties from application.properties will override those in application.yml. It's generally best practice to choose one format and stick with it to avoid confusion.


Accessing Configuration Properties in Code

Defining properties is only half the story; you also need a way to access these values in your application code. Spring provides several mechanisms.

Using @Value

The simplest way to inject a single property is with the @Value annotation. You use "property placeholder" syntax (${...}) to specify the key.

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

@Component
public class MyComponent {

    @Value("${app.greeting}")
    private String greeting;

    // You can also provide a default value using a colon
    @Value("${app.some.other.property:default value}")
    private String propertyWithDefault;

    public void sayHello() {
        System.out.println(greeting);
        System.out.println(propertyWithDefault);
    }
}

Type-safe Binding with @ConfigurationProperties

While @Value is fine for a few properties, it can become cumbersome and error-prone when dealing with a large, structured block of configuration. A much cleaner, more robust, and type-safe approach is to use the @ConfigurationProperties annotation.

This annotation binds a whole section of your configuration file to the fields of a Java class. This is particularly powerful when using immutable Java 17 records for configuration objects.

  1. Define your properties:

    
    
    
    # in application.yml
    api:
      client:
        url: "https://api.example.com"
        timeout-seconds: 5
        retries: 3
    
  2. Create a configuration properties record:

    import org.springframework.boot.context.properties.ConfigurationProperties;
    
    @ConfigurationProperties(prefix = "api.client")
    public record ApiClientConfig(String url, int timeoutSeconds, int retries) {
    }
    

    The prefix tells Spring Boot to look for properties starting with api.client. The rest of the key (e.g., url) is automatically mapped to the record's components. Spring Boot also handles type conversion (e.g., from "5" to int 5).

  3. Enable and inject it:

    import org.springframework.boot.context.properties.EnableConfigurationProperties;
    import org.springframework.stereotype.Service;
    
    @Service
    @EnableConfigurationProperties(ApiClientConfig.class) // Tell Spring to create a bean of ApiClientConfig
    public class MyApiService {
    
        private final ApiClientConfig config;
    
        // Inject the configuration bean via the constructor
        public MyApiService(ApiClientConfig config) {
            this.config = config;
        }
    
        public void connect() {
            System.out.println("Connecting to " + config.url());
            System.out.println("Timeout is " + config.timeoutSeconds() + " seconds.");
        }
    }
    

This approach is highly recommended as it provides compile-time safety and keeps related configuration neatly organized. For an overview of these access methods, you can refer back to the Baeldung article.

Using application.yml vs application.properties in Spring Boot

The Baeldung article also covers how to access the properties you've defined.

Read 'Section 4. Spring Boot Usage'. It covers @Value, the Environment abstraction (a programmatic way to access properties), and @ConfigurationProperties.


Externalization: Overriding Properties for Different Environments

One of the most powerful features of Spring Boot's configuration system is its property overriding mechanism. The application.properties file inside your JAR provides the defaults, but these can be overridden by numerous external sources. This allows you to use the exact same application artifact (the compiled .jar file) across different environments (development, testing, production) simply by providing different external configurations.

Spring Boot has a very specific hierarchy of property sources. A property defined in a source with higher precedence will override the same property from a source with lower precedence.

Here are some of the most common sources, ordered from highest to lowest precedence:

  1. Command-line arguments: e.g., java -jar myapp.jar --server.port=9000
  2. OS Environment variables: e.g., export SERVER_PORT=9000 (Note: Spring Boot's relaxed binding maps SERVER_PORT to server.port)
  3. Application properties outside of your packaged jar: An application.properties or application.yml file in the same directory as the .jar file.
  4. Application properties packaged inside your jar: The application.properties or application.yml inside src/main/resources.

The following video from Java Brains provides an excellent, practical demonstration of this overriding mechanism.

Using external property sources with Spring Boot - Microservice configuration with Spring Boot [04]

Watch this demonstration to see how properties packaged inside a JAR can be overridden by an external file and by command-line arguments.

Watch from 01:38 to 05:19. The video first shows how placing an application.properties file next to the executable JAR overrides the internal one. It then shows how a command-line argument can override both. This clearly illustrates the precedence hierarchy.

This tiered approach is incredibly flexible. You can ship your application with sensible defaults, allow system administrators to override them with a configuration file on the server, and provide one-off overrides via command-line arguments for debugging or specific tasks, all without ever touching the application code.

The "Spring Tips: Configuration" blog post provides further context on this, framing it within the 12-Factor App principles.

Spring Tips: Configuration

This blog post from the official Spring team reinforces these concepts, particularly the importance of externalizing configuration.

Read the section that begins 'Incidentally, you could also run the application with the configuration that lives outside the application...' and the section that begins 'Earlier, we looked at how to specify a profile... This mechanism... is a general-purpose.' These sections reinforce the overriding concept and tie it to best practices like the 12-factor manifesto.


Conclusion

In this lesson, we've unpacked the core of Spring Boot's configuration mechanism. You now understand how to define, manage, and access the settings that drive your application's behavior.

Key Takeaways:

  • Centralized Configuration: Spring Boot automatically loads configuration from application.properties or application.yml in src/main/resources.
  • Properties vs. YAML: You can choose between the simple key-value .properties format and the more readable, hierarchical .yml format.
  • Type-Safe Access: While @Value is useful for single properties, @ConfigurationProperties is the superior method for binding structured, related properties to type-safe Java objects.
  • Externalization is Key: Spring Boot's property source hierarchy allows you to override default configurations using external files, environment variables, or command-line arguments. This enables a single build artifact to be deployed across multiple environments.

You've learned how to manage individual properties. However, when dealing with entire environments like dev, qa, and prod, you often need to change a whole group of properties at once. In our next lesson, we will explore Spring Profiles, a powerful feature that allows you to segregate parts of your application configuration and make them active only in specific environments.