@Value Annotation in Spring Explained
Fast recall
Quick revision
Core answer
Property injection knowledge and understanding of externalized configuration in Spring
Not knowing the difference between ${} for property placeholders and #{} for SpEL expressions
Explain the difference between ${} for property values and #{} for SpEL expressions with concrete examples
Interview-ready guide
Interview answer
A constructor can accept @Value("${payment.timeout:5s}") Duration timeout. Spring resolves the winning property source and converts the text to Duration when conversion support is available. A missing required placeholder normally fails context creation, which is useful for required configuration. Do not hide a required secret behind an unsafe default. For base URL, timeout, retry count, and credentials together, bind PaymentProperties instead.
@Value Annotation in Spring Explained
Direct Answer
@Value can inject an individual property placeholder such as ${server.port}, a default such as ${timeout:30}, or a Spring Expression Language expression such as #{2 * 5} into a Spring-managed bean. Use it for a small number of isolated settings. Use @ConfigurationProperties for a related group that benefits from type-safe binding and validation.
Code Example
@Service
public class PaymentService {
private final String apiKey;
private final int timeout;
private final boolean featureEnabled;
private final double calculatedRate;
public PaymentService(
@Value("${payment.api.key}") String apiKey, // Property from application.properties
@Value("${payment.timeout:5000}") int timeout, // Default 5000 if not set
@Value("${features.new-checkout:false}") boolean featureEnabled, // Boolean property
@Value("#{${payment.base.rate} * 1.15}") double calculatedRate) { // SpEL expression
this.apiKey = apiKey;
this.timeout = timeout;
this.featureEnabled = featureEnabled;
this.calculatedRate = calculatedRate;
}
public void processPayment(Order order) {
System.out.println("Using API key: " + apiKey.substring(0, 5) + "...");
System.out.println("Timeout: " + timeout + "ms");
if (featureEnabled) {
System.out.println("New checkout flow with rate: " + calculatedRate);
}
}
}
Common Mistakes & Pitfalls
- Confusing ${} and #{}: Freshers often mix up dollar-brace for property placeholders and hash-brace for SpEL. ${server.port} reads a property, #{2 + 2} evaluates an expression. Using ${2 + 2} won't compute anything, it'll look for a property literally named "2 + 2".
- Forgetting defaults for optional properties: If you use @Value("${optional.feature}") without a default and the property is missing, the app crashes at startup. Always provide defaults with colon: ${optional.feature:false}.
- Using @Value on non-Spring beans: If you create a class with new PaymentService(), @Value does nothing. Spring must create the bean for injection to work.
- Hardcoding values instead of externalizing: Freshers sometimes use @Value("localhost") instead of @Value("${database.host}"). The whole point is to read from properties files so you can change config without recompiling.
Check your understanding
Answer these without looking back at the article.
- What is the difference between @Value with ${} and #{}?
- How do you inject a list from application.properties?
- When should you use @ConfigurationProperties instead of @Value?
Looking for a structured roadmap?
Every module on this page is also part of the full Java backend interview track.