DEV Community

Cover image for Spring Boot @Value Property Order Explained
Ashutosh Krishna
Ashutosh Krishna

Posted on • Originally published at blog.ashutoshkrris.in

Spring Boot @Value Property Order Explained

If you’ve ever been in a Spring Boot interview, you’ve probably come across this question:

“Where does Spring Boot look for @Value("${my.property:DEFAULT_VALUE}"), and in what order?”

At first, it might sound straightforward, but it actually tests a developer’s understanding of how Spring Boot resolves configuration properties — a concept that directly impacts how applications behave across environments.

Understanding the configuration hierarchy in Spring Boot is essential because it helps you:

  • Debug issues when the wrong value is picked up.

  • Control how environment variables and external configurations override defaults.

  • Manage different environments such as development, staging, and production in CI/CD pipelines.

In this article, we’ll look at how @Value works, the exact order in which Spring Boot looks for property values, and why this knowledge is crucial for building predictable and maintainable applications.

Understanding the @Value Annotation

The @Value annotation in Spring Boot is used to inject values into fields directly from property sources such as application.properties, application.yml, environment variables, or command-line arguments. It allows you to bind configuration values to variables in your code without hardcoding them.

Here’s a simple example:

@Value("${my.property:DEFAULT_VALUE}")
private String myProperty;
Enter fullscreen mode Exit fullscreen mode

In this example:

  • my.property is the key whose value Spring Boot will try to resolve.

  • DEFAULT_VALUE is the fallback value that will be used if the property is not found in any configuration source.

This default value mechanism is very useful. It ensures your application does not fail to start even if a configuration is missing. Instead, Spring Boot will inject the specified default, keeping your application stable and predictable.

Using @Value is a simple way to access configuration properties for small or single-value injections. For more complex or grouped configurations, developers often use @ConfigurationProperties, which we’ll discuss later.

Where Does Spring Boot Look for Properties (Order of Resolution)

When you use @Value or any other property injection mechanism, Spring Boot doesn’t just look in one place for configuration values. It searches across multiple sources in a specific priority order.

This order determines which value is finally injected when the same property key appears in different places. The higher the source is in the list, the greater its priority.

Here’s the general order in which Spring Boot resolves properties (based on the SpringApplication configuration sources):

Priority Source Example / Notes
1 Command-line arguments e.g. --my.property=value when running the application
2 Java System properties e.g. -Dmy.property=value
3 OS environment variables e.g. export MY_PROPERTY=value
4 Application properties or YAML files Located in src/main/resources/application.properties or .yml
5 Profile-specific configuration files e.g. application-dev.properties when spring.profiles.active=dev
6 External configuration files Files located in a /config directory outside the packaged JAR
7 JNDI attributes Used in servlet containers or enterprise environments
8 Random values e.g. ${random.uuid}, ${random.int} generated by Spring Boot
9 Default value in code The fallback provided in @Value("${my.property:default}")

Spring Boot checks these sources in order — from top to bottom — and uses the first value it finds for a given property key.

This hierarchy allows you to easily override configurations at runtime without changing your code. For example, values from command-line arguments or environment variables can override those in your application files, which is especially useful for deploying the same codebase to multiple environments like development, testing, and production.

Example Demonstration

Let’s look at a simple example to understand how Spring Boot decides which property value to use when multiple sources define the same key.

Imagine the following project structure:

src/
 └─ main/resources/
     ├─ application.properties
     ├─ application-dev.properties
Enter fullscreen mode Exit fullscreen mode

Step 1: Define properties in both files

application.properties

my.property=HelloFromApplication
Enter fullscreen mode Exit fullscreen mode

application-dev.properties

my.property=HelloFromDevProfile
Enter fullscreen mode Exit fullscreen mode

Step 2: Use @Value in your code

@Value("${my.property:DefaultHello}")
private String message;
Enter fullscreen mode Exit fullscreen mode

Step 3: Run the application with different configurations

Case 1: Default profile (no active profile)

If you run your Spring Boot app normally:

java -jar myapp.jar
Enter fullscreen mode Exit fullscreen mode

Spring Boot will load application.properties and inject the value:

HelloFromApplication
Enter fullscreen mode Exit fullscreen mode

Case 2: Active profile set to “dev”

If you run:

java -jar myapp.jar --spring.profiles.active=dev
Enter fullscreen mode Exit fullscreen mode

Spring Boot will load both application.properties and application-dev.properties, but the profile-specific file has higher priority.

So the value becomes:

HelloFromDevProfile
Enter fullscreen mode Exit fullscreen mode

Case 3: Override from the command line

Now, if you run:

java -jar myapp.jar --my.property=HelloFromCLI
Enter fullscreen mode Exit fullscreen mode

Command-line arguments take the highest priority, so this overrides everything else:

HelloFromCLI
Enter fullscreen mode Exit fullscreen mode

Case 4: No property found anywhere

If you remove the property from all configuration files and don’t pass it as an argument, Spring Boot uses the default value given in the code:

DefaultHello
Enter fullscreen mode Exit fullscreen mode

This example shows how Spring Boot’s property resolution order allows flexible configuration management. You can define defaults in your code, keep environment-specific values in property files, and still override them at runtime when needed.

Common Pitfalls

Even though Spring Boot’s configuration system is powerful, it’s easy to run into small mistakes that cause unexpected behavior. Here are some common pitfalls developers face when working with @Value and property resolution.

1. Forgetting to Set the Active Profile

Spring Boot supports profile-specific configuration files, such as application-dev.properties or application-prod.properties.

However, these files are only used when the corresponding profile is active. If you forget to set the profile, Spring Boot will ignore those files and fall back to the default application.properties.

For example:

java -jar myapp.jar --spring.profiles.active=dev
Enter fullscreen mode Exit fullscreen mode

Without this argument, your application-dev.properties file won’t be loaded at all.

2. Unintentional Property Overrides

Because Spring Boot merges multiple property sources, it’s possible to accidentally override values from one source with another.

A common case is when an environment variable or command-line argument unintentionally replaces a property defined in your configuration file.

For instance, if your system has an environment variable named MY_PROPERTY, it might override the my.property key from your .properties file. Always check the effective configuration when debugging unexpected values.

3. Confusing @Value and @ConfigurationProperties

Both @Value and @ConfigurationProperties are used to inject configuration values, but they serve different purposes.

Feature @Value @ConfigurationProperties
Best for Single values Grouped or structured properties
Type safety Limited Strong (binds directly to fields)
Supports validation No Yes
Preferred for large configs
  • Use @Value when you only need a few properties.

  • Use @ConfigurationProperties when dealing with a group of related configurations (for example, database settings or API credentials).

Choosing the right one helps keep your configuration clean, organized, and easy to maintain.

Interview Tip / Summary

When asked about property resolution in Spring Boot interviews, it’s not just about recalling the list — it’s about showing that you understand how and why it works that way.

Here are the key points to keep in mind:

  1. Spring Boot merges multiple property sources — it doesn’t rely on a single file.

  2. Higher-priority sources override lower-priority ones — values from the command line or environment variables can replace those in your application files.

  3. @Value("${my.property:DEFAULT}") provides a safety net — the default value ensures your application runs even when the property is missing.

Quick Mnemonic to Remember the Order

You can remember the lookup order with this simple phrase:

“CLI → System → Env → App → Default”

Or think of it as:

Command-line arguments
↓
System properties (-D)
↓
Environment variables
↓
Application files (.properties / .yml)
↓
Default value in code
Enter fullscreen mode Exit fullscreen mode

If you end your interview answer with a short, clear explanation like this:

“Spring Boot checks multiple property sources in a specific order — starting from command-line arguments, system properties, environment variables, and application files, before finally using the default value provided in code.”

—you’ll leave a confident and lasting impression.

Frequently Asked Questions (FAQ)

1. What happens if a property is missing and no default value is given?

If a property key cannot be found in any configuration source and you haven’t provided a default value in your @Value expression, Spring Boot will throw an exception during startup.

For example:

@Value("${my.property}")
private String value;
Enter fullscreen mode Exit fullscreen mode

If my.property is not defined anywhere, you’ll see an error like:

Caused by: java.lang.IllegalArgumentException: Could not resolve placeholder 'my.property' in value "${my.property}"
Enter fullscreen mode Exit fullscreen mode

To prevent this, always provide a fallback value:

@Value("${my.property:DefaultValue}")
private String value;
Enter fullscreen mode Exit fullscreen mode

This ensures your application starts smoothly, even when the property is missing.

2. How does @ConfigurationProperties differ from @Value?

While both are used to inject configuration values, they are suited to different use cases:

  • @Value is ideal for single values or small configurations.

    Example:

    @Value("${server.port:8080}")
    private int port;
    
  • @ConfigurationProperties is better for structured or grouped configurations, such as database or API settings. It binds multiple related properties into a single Java object and supports validation.

    Example:

    @ConfigurationProperties(prefix = "app")
    public class AppConfig {
        private String name;
        private String version;
    }
    

In short, use @Value for simple injections and @ConfigurationProperties for larger, type-safe configurations.

3. Can we override properties at runtime?

Yes, you can override properties at runtime without changing your code.

Spring Boot allows this through various property sources, such as:

  • Command-line arguments

    java -jar myapp.jar --server.port=9090
    
  • Environment variables

    export SERVER_PORT=9090
    
  • System properties

    java -Dserver.port=9090 -jar myapp.jar
    

These dynamic overrides are particularly useful in CI/CD pipelines or cloud environments, where configurations may differ between development, staging, and production.

Top comments (0)