Careeroza
Reading Values with Value
The @Value Annotation
Inject a single setting into a bean with @Value("${key}"). Add a default after a colon: ${key:default}. Spring converts the text to the field type (int, boolean, Duration, List).
package com.shopease.order;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
@Service
public class DeliveryChargeService {
private final int freeDeliveryAbove;
private final int deliveryCharge;
private final String currency;
public DeliveryChargeService(@Value("${shopease.free-delivery-above}") int freeDeliveryAbove,
@Value("${shopease.delivery-charge:40}") int deliveryCharge, // default 40
@Value("${shopease.currency}") String currency) {
this.freeDeliveryAbove = freeDeliveryAbove;
this.deliveryCharge = deliveryCharge;
this.currency = currency;
}
public String chargeFor(int cartTotal) {
int charge = cartTotal >= freeDeliveryAbove ? 0 : deliveryCharge;
return charge + " " + currency;
}
}Placeholders and Defaults in Plain Java
Example
A simplified version of how Spring resolves ${key:default} placeholders, including references to other keys and environment-style values:
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Main {
static final Pattern PLACEHOLDER = Pattern.compile("\\$\\{([^:}]+)(?::([^}]*))?}");
static String resolve(String text, Map<String, String> props) {
Matcher m = PLACEHOLDER.matcher(text);
StringBuilder out = new StringBuilder();
while (m.find()) {
String value = props.getOrDefault(m.group(1), m.group(2));
if (value == null) throw new IllegalArgumentException("Could not resolve placeholder '" + m.group(1) + "'");
m.appendReplacement(out, Matcher.quoteReplacement(resolve(value, props)));
}
m.appendTail(out);
return out.toString();
}
public static void main(String[] args) {
Map<String, String> props = Map.of(
"shopease.currency", "INR",
"server.port", "8081",
"shopease.base-url", "http://localhost:${server.port}");
System.out.println(resolve("${shopease.currency}", props));
System.out.println(resolve("${shopease.delivery-charge:40}", props));
System.out.println(resolve("${shopease.base-url}/api/products", props));
try {
resolve("${razorpay.key}", props);
} catch (IllegalArgumentException e) {
System.out.println("Error: " + e.getMessage());
}
}
}Output
INR 40 http://localhost:8081/api/products Error: Could not resolve placeholder 'razorpay.key'
Note: A missing key with no default stops the app at startup with Could not resolve placeholder 'razorpay.key' in value "${razorpay.key}". That is good: you find config mistakes immediately, not in production traffic.
When to Use What
@Value is perfect for one or two values. For a group of related settings (shopease.*), the medium level shows @ConfigurationProperties, which binds them into a typed, validated object.