When developing Spring Boot applications, you need to manage various configurations such as database connection details, server ports, and log levels. These settings are handled through configuration files like application.properties and application.yml.

However, beginners often have questions like “Which file format should I use?”, “How do I load environment variables?”, and “When should I use @Value vs @ConfigurationProperties?”

This article provides a practical guide covering everything from the basics of configuration files to how to use them effectively in real-world projects.

Configuration File Basics - properties vs yml

Spring Boot configuration files externalize settings such as database connection details and server ports. Placing them in the src/main/resources directory is all it takes for them to be loaded automatically.

The two main formats are application.properties (key=value format) and application.yml (YAML format).

# application.properties
server.port=8080
spring.datasource.url=jdbc:mysql://localhost:3306/mydb
# application.yml
server:
  port: 8080
spring:
  datasource:
    url: jdbc:mysql://localhost:3306/mydb

For simple settings, properties works fine; for deeply nested configurations, yml tends to be more readable. That said, the most important thing is to match the format already used in your existing project. If both files are present, properties takes precedence.

Loading a Single Configuration Value with @Value

The simplest way to use configuration values in Java code is the @Value annotation.

# application.properties
app.name=MySpringBootApp
app.timeout=30
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

@Component
public class AppConfig {
    @Value("${app.name}")
    private String appName;

    @Value("${app.timeout:30}")  // Falls back to 30 if not defined
    private int timeout;
}

@Value is convenient for reading individual configuration values, but when there are many related settings, @ConfigurationProperties (covered next) is the better choice.

When multiple related properties exist, grouping them with @ConfigurationProperties makes the configuration type-safe and easier to manage.

# application.yml
app:
  database:
    host: localhost
    port: 3306
@ConfigurationProperties(prefix = "app.database")
public record DatabaseProperties(String host, int port) {}

Enable it in your main class and inject it where needed.

@SpringBootApplication
@EnableConfigurationProperties(DatabaseProperties.class)
public class MyApplication { ... }

@Service
public class DatabaseService {
    private final DatabaseProperties props;
    // Injected via constructor
}

Use @Value for a single configuration value, and @ConfigurationProperties when you have a group of related settings.

Overriding Production Settings with Environment Variables

Sensitive information such as passwords should be managed via environment variables. Spring Boot automatically maps property names to environment variables by converting dots and hyphens to underscores and lowercasing to uppercasing.

For example, spring.datasource.password can be overridden with the environment variable SPRING_DATASOURCE_PASSWORD.

spring:
  datasource:
    password: ${DB_PASSWORD:defaultpassword}
export DB_PASSWORD=super-secure-password
java -jar myapp.jar

Reusing Configuration Values with Placeholders

You can reference other property values using the ${} placeholder syntax.

app.base-url=https://api.example.com
app.endpoint.users=${app.base-url}/users

# Falls back to default value if the environment variable is not defined
server.port=${SERVER_PORT:8080}

Understanding Property Priority

When loading configuration from multiple sources, the priority order is as follows (higher in the list means higher priority):

  1. Command-line arguments
  2. OS environment variables
  3. application-{profile}.properties/yml
  4. application.properties/yml

To switch configurations per environment, use Profiles.

java -jar myapp.jar --spring.profiles.active=prod

For more details on Profiles, see “How to Safely Switch Environment-Specific Configuration Using Spring Boot Profiles”.

Common Pitfalls

Here are a few errors you are likely to encounter with configuration files.

Property not being loaded

If ${key} appears as a literal string with @Value, you likely have a typo in the key name or the class is missing the @Component annotation. Also verify that the configuration file is located under src/main/resources.

YAML indentation errors

YAML does not allow tab characters. Use consistent 2-space indentation. IDE YAML support can catch these errors before they cause problems at runtime.

Environment variable not taking effect

Environment variable names must use underscores and uppercase — spring.datasource.password becomes SPRING_DATASOURCE_PASSWORD. Dots and hyphens are replaced with underscores, and all letters are uppercased.

Summary

Spring Boot configuration management is straightforward: externalize settings into properties or yml files, and load them using @Value or @ConfigurationProperties.

In production, override sensitive information like passwords with environment variables and use Profiles to switch between environment-specific configurations. Understanding property priority helps prevent unintended configuration overrides.

Keep these practices in mind for real-world projects:

  • Never write sensitive information in configuration files — use environment variables instead
  • Group related settings using @ConfigurationProperties
  • Agree on a single configuration file format within your team

Mastering the basics of configuration management enables you to build applications that adapt flexibly to different environments.