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
@ValueAnnotation - Where Does Spring Boot Look for Properties (Order of Resolution)
- Example Demonstration
- Common Pitfalls
- Interview Tip / Summary
- Frequently Asked Questions (FAQ)
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;
In this example:
my.propertyis the key whose value Spring Boot will try to resolve.DEFAULT_VALUEis 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
Step 1: Define properties in both files
application.properties
my.property=HelloFromApplication
application-dev.properties
my.property=HelloFromDevProfile
Step 2: Use @Value in your code
@Value("${my.property:DefaultHello}")
private String message;
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
Spring Boot will load application.properties and inject the value:
HelloFromApplication
Case 2: Active profile set to “dev”
If you run:
java -jar myapp.jar --spring.profiles.active=dev
Spring Boot will load both application.properties and application-dev.properties, but the profile-specific file has higher priority.
So the value becomes:
HelloFromDevProfile
Case 3: Override from the command line
Now, if you run:
java -jar myapp.jar --my.property=HelloFromCLI
Command-line arguments take the highest priority, so this overrides everything else:
HelloFromCLI
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
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
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
@Valuewhen you only need a few properties.Use
@ConfigurationPropertieswhen 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:
Spring Boot merges multiple property sources — it doesn’t rely on a single file.
Higher-priority sources override lower-priority ones — values from the command line or environment variables can replace those in your application files.
@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
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;
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}"
To prevent this, always provide a fallback value:
@Value("${my.property:DefaultValue}")
private String value;
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:
-
@Valueis ideal for single values or small configurations.
Example:
@Value("${server.port:8080}") private int port; -
@ConfigurationPropertiesis 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)