๐ A surprising Spring Boot moment I didn't expect — and the rabbit hole it took me down...
๐ฌ It All Started With a Simple Idea...
You know how it goes…
You define a config value like this in application.properties
:
payment.currency=INR
And then you boldly write this innocent-looking code:
@Component
public class PaymentUtil {
@Value("${payment.currency}")
private static String currency; // ✅ Logical! Right?
public static void printCurrency() {
System.out.println("Currency: " + currency);
}
}
You run the app. And BAM ๐ฅ
Currency: null
๐ต "Eh? I clearly defined the property. Is it not reading the file? Do I need a restart? Do I need to yell at my laptop?"
๐คฏ The Shocking Discovery
Spring doesn’t inject values into static fields.
Yes, my friend. Even if you beg it with @Value
.
And trust me — it’s not a bug. It’s a feature. ๐
๐ง What Is This Dependency Injection (DI) Sorcery Anyway?
Let’s take a detour (the good kind — not the Bangalore traffic kind).
Spring uses Dependency Injection (DI) to manage your object graph using:
- ๐
@Component
/@Service
/@Repository
- ๐
@Autowired
/@Value
/ Constructor injection - ๐ Reflection magic ๐ฉ✨
๐ง Why Static Fields Break the Magic
Spring manages beans as instances — objects in the ApplicationContext.
But static fields belong to the class itself, not an object.
// Instance-level: Works ✔️
@Component
public class ConfigReader {
@Value("${app.name}")
private String name;
}
// Static field: No bean owns it ❌
@Value("${app.name}")
private static String name;
So Spring scans the class and goes:
“Aha, no instance variable to inject into? Cool, I’ll move on.” ๐
That’s why:
- ❌ You get
null
- ❌ Or default values
- ❌ Or you stare at the screen questioning your life choices ๐ซ
๐ ️ The Correct Fix That Surprised Me
✅ Option 1: Use @PostConstruct to Bridge Static + Instance
@Component
public class PaymentUtil {
@Value("${payment.currency}")
private String currency;
private static String staticCurrency;
@PostConstruct
public void init() {
staticCurrency = currency;
}
public static String getCurrency() {
return staticCurrency;
}
}
๐ Now currency is injected properly by Spring.
✅ Option 2: Use @ConfigurationProperties — The Cleaner Way
@Component
@ConfigurationProperties(prefix = "payment")
public class PaymentConfig {
private String currency;
public String getCurrency() { return currency; }
public void setCurrency(String currency) { this.currency = currency; }
}
@Component
public class PaymentUtil {
private final PaymentConfig config;
public PaymentUtil(PaymentConfig config) {
this.config = config;
}
public void printCurrency() {
System.out.println("Currency: " + config.getCurrency());
}
}
๐งผ Much cleaner, and easier to unit test!
๐ง But Wait… Why Can’t Spring Just Inject Into Static?
Let’s dig deeper.
- ๐ฆ Create object of the bean (e.g., PaymentUtil)
- ๐ Reflectively access fields
- ๐ Inject values from application context
- ๐ Initialize the bean
But static fields don’t belong to any bean instance. So Step 2 breaks:
๐งต “Oops! There’s no object for me to inject into.”
It’s like trying to insert a USB drive into a photo of a laptop. ๐
๐ Dumb Interview Question, Smart Answer
Q: "Can Spring inject values into static fields?"
A: "Only if Spring becomes a Jedi and rewrites the Java language spec."
๐งช Curious? Try This Yourself!
# application.properties
payment.currency=USD
@Component
public class TestUtil {
@Value("${payment.currency}")
private static String currency;
public static void main(String[] args) {
System.out.println("Currency = " + currency);
}
}
Currency = null // ๐
๐งผ So What Did I Learn?
- ๐ฒ I Did This:
@Value
on a static field - ๐ค Expected: "INR"
- ❌ Got:
null
- ✅ Fixed By:
@PostConstruct
or@ConfigurationProperties
- ๐ก Lesson: Spring doesn’t inject into static — by design
๐ Wrapping Up: From "What The Null?!" to "Aha!"
This was a “Why is it null?” moment that led to one of my best Spring learnings:
Spring is smart, but it only manages beans it creates.
Static fields live in their own world — away from the Spring container.
Always remember: With great power comes great bean lifecycle responsibility. ๐ธ️
๐ค Over to You!
Ever had a “Null surprise” like this in your config or bean wiring?
๐ Share your moment in the comments — let’s laugh and learn together! ๐
Comments
Post a Comment