Skip to main content

๐ŸฅŠ @Component vs @Configuration — Not Just Cousins in Spring! ๐Ÿ˜ฒ

 ๐Ÿง  Ever looked at these two annotations and thought:

“Aren’t they doing the same thing?”
Welcome to the club. I had the same confusion until... I went deep down the Spring rabbit hole ๐Ÿ•ณ️๐Ÿ‡

Let’s clear this once and for all — with real differences, examples, gotchas, and even a few bad jokes along the way ๐Ÿ˜Ž


๐ŸŒŸ The Basic Definitions

Annotation Meaning
@Component A general-purpose stereotype indicating a class is a Spring-managed bean
@Configuration A specialized class used to declare beans via @Bean methods

๐Ÿ’ก Both register beans with Spring — but what happens behind the scenes is where it gets spicy ๐ŸŒถ️


๐Ÿค” But Aren’t They Both Just “Beans”?

Short answer: Yes.
Long answer: It’s complicated — like your last relationship ๐Ÿ’”.


⚙️ INTERNAL MAGIC: The Real Difference

1. @Configuration Uses CGLIB Proxy for Singleton ๐Ÿ’ซ

When you mark a class with @Configuration, Spring uses CGLIB subclassing (AOP-style proxying) to make sure all @Bean methods return the same singleton — even if called multiple times.

๐Ÿ’ฃ Example:


@Configuration
public class MyConfig {

    @Bean
    public Engine engine() {
        return new Engine(); // always returns same Engine
    }

    @Bean
    public Car car() {
        return new Car(engine()); // uses proxied engine()
    }
}


๐Ÿ“Œ Result:
Spring intercepts engine() call inside car() and reuses the same singleton object.


2. @Component Doesn’t Use CGLIB Proxy ๐Ÿ˜

If you do this:


@Component
public class MyConfig {

    @Bean
    public Engine engine() {
        return new Engine(); // ๐Ÿ˜ต This gets called multiple times!
    }

    @Bean
    public Car car() {
        return new Car(engine()); // Creates a new Engine every time
    }
}


๐Ÿ’ฅ Boom! Now car() and engine() use different objects — no proxying here.

๐Ÿง  This is why Spring recommends using @Configuration for bean factories, not @Component.


๐Ÿ›ก️ Singleton Is Not Just a Pattern — It’s a Proxy Game

Without CGLIB proxying, Spring cannot guarantee singleton behavior across bean methods. That’s why:

  • @Configuration = Proxy-magic ๐Ÿช„ + Full bean lifecycle control
  • @Component = Regular class ๐Ÿงฑ with Spring bean creation only

๐Ÿ•ต️‍♂️ Real-World Gotcha You Didn’t Know

❗ Changing @Configuration to @Component breaks singleton!

You might have seen this subtle bug in interviews or production:

You might have seen this subtle bug in interviews or even production:

@Configuration
public class MyConfig {
   ...
}

➡️ Someone changes it to:

@Component
public class MyConfig {
   ...
}

๐ŸŽฏ Guess what? It still works… but beans aren’t singleton anymore ๐Ÿ˜ฑ




✅ Why We Use @Component — And How Spring Knows What to Wire ๐Ÿ”Œ

Let’s say you wrote a simple utility class like this:


@Component public class EmailUtil { public void send(String to, String body) { System.out.println("Sending email to " + to); } }

Now… how does Spring know this class even exists? And how do we use it?


๐Ÿ“Œ Step 1: Mark with @Component

This tells Spring:

“Hey, please manage this class. Make an object, keep it ready, I’ll be needing it.” ๐Ÿ˜„

Spring adds it to the ApplicationContext during startup (if it's in a scanned package).


๐Ÿ“Œ Step 2: Inject It Using @Autowired or Constructor Injection


@Service public class NotificationService { private final EmailUtil emailUtil; @Autowired public NotificationService(EmailUtil emailUtil) { this.emailUtil = emailUtil; } public void notifyUser() { emailUtil.send("me@example.com", "Your order is shipped!"); } }

Now Spring will auto-wire EmailUtil wherever it's needed!


๐Ÿ”„ So the Flow Looks Like This:

  1. You annotate EmailUtil with @Component

  2. Spring finds it via @ComponentScan during startup ๐Ÿ”

  3. You use @Autowired (or constructor injection) to inject it into another class ๐Ÿšš

  4. Spring sees the request and wires the singleton instance of EmailUtil ๐Ÿช„


๐Ÿคฏ What If You Don’t Annotate It with @Component?

Then Spring won’t even know it exists
→ You'll get a NoSuchBeanDefinitionException when you try to inject it.


๐ŸŽญ Use Cases — When to Use What?

Use This For... Annotation
Declaring beans with @Bean @Configuration ✅
General Spring component scan @Component ✅


๐Ÿ˜‚ Funny Analogy

Imagine @Component is like a coffee shop ๐Ÿช.
You order coffee ☕, and they make a new one each time.
But @Configuration is like your mom’s kitchen ๐Ÿ  —
She remembers what you ordered last week and says:

"Son, manage with one cup... memory is limited here too, like our heap space!" ๐Ÿง ๐Ÿ’‍♀️


๐Ÿง  Summary — The Final Showdown

Feature @Component @Configuration
Spring Bean Registration
Proxy Bean Method Calls ✅ (CGLIB)
Ensures Singleton
Use with @Bean methods ๐Ÿšซ Avoid ✅ Recommended

๐ŸŽจ Bonus: Colorful Icons for Memory ๐Ÿง 

  • ๐Ÿ”ง @Component = Generic Tool

  • ๐Ÿ—️ @Configuration = Master Builder with Memory

  • ๐Ÿงช @Bean = Custom-Made Ingredient

  • ๐Ÿ”‚ CGLIB = Behind-the-scenes Repeater


๐Ÿคน Wrapping Up

So next time someone says “@Component and @Configuration are same,”
just drop this truth bomb ๐Ÿ’ฃ:

Only one of them respects Singleton. The other one? It’s freelancing ๐Ÿ˜Ž

๐Ÿ’ฌ Got more such hidden Spring secrets or confusion?
Drop a comment — I love exploring the “whys” behind the “hows”!

Comments

Popular posts from this blog

๐Ÿ” Is final Really Final in Java? The Truth May Surprise You ๐Ÿ˜ฒ

๐Ÿ’ฌ “When I was exploring what to do and what not to do in Java, one small keyword caught my eye — final . I thought it meant: locked, sealed, frozen — like my fridge when I forget to defrost it.”   But guess what? Java has its own meaning of final… and it’s not always what you expect! ๐Ÿ˜… Let’s break it down together — with code, questions, confusion, jokes, and everything in between. ๐ŸŽฏ The Confusing Case: You Said It's Final... Then It Changed?! ๐Ÿซ  final List<String> names = new ArrayList <>(); names.add( "Anand" ); names.add( "Rahul" ); System.out.println(names); // [Anand, Rahul] ๐Ÿคฏ Hold on... that’s final , right?! So how on earth is it still changing ? Time to dive deeper... ๐Ÿง  Why Is It Designed Like This? Here’s the key secret: In Java, final applies to the reference , not the object it points to . Let’s decode this like a spy mission ๐Ÿ•ต️‍♂️: Imagine This: final List<String> names = new ArrayList <>(); Be...

๐ŸŒŸ My Journey – From Zero to Senior Java Tech Lead ๐ŸŒŸ

 There’s one thing I truly believe… If I can become a Java developer, then anyone in the world can. ๐Ÿ’ฏ Sounds crazy? Let me take you back. ๐Ÿ•“ Back in 2015… I had zero coding knowledge . Not just that — I had no interest in coding either. But life has its own plans. In 2016, I got a chance to move to Bangalore and joined a Java course at a training center. That’s where it all started — Every day, every session made me feel like: "Ohhh! Even I can be a developer!" That course didn’t just teach Java — it gave me confidence . ๐Ÿงช Two Life-Changing Incidents 1️⃣ The Interview That Wasn't Planned Halfway through my course, I had to urgently travel to Chennai to donate blood to a family member. After that emotional rollercoaster, I found myself reflecting on my skills and the future. The next day, as I was preparing for my move to Bangalore to complete the remaining four months of my course, I randomly thought — "Let me test my skills... let me just see...

๐ŸŽข Java Loops: Fun, Fear, and ForEach() Fails

๐ŸŒ€ Oops, I Looped It Again! — The Ultimate Java Loop Guide You Won't Forget “I remember this question from one of my early interviews — I was just 2 years into Java and the interviewer asked, ‘Which loop do you prefer and why?’” At first, I thought, “Duh! for-each is cleaner.” But then he grilled me with cases where it fails. ๐Ÿ˜ต That led me to explore all loop types, their powers, and their pitfalls. Let’s deep-dive into every major Java loop with examples &  real-world guidance so you'll never forget again. ๐Ÿ” Loop Type #1: Classic For Loop — “The Old Reliable” ✅ When to Use: You need an index You want to iterate in reverse You want full control over loop mechanics ✅ Good Example: List<String> names = List.of("A", "B", "C"); for (int i = 0; i < names.size(); i++) { System.out.println(i + ": " + names.get(i)); } ๐Ÿ”ฅ Reverse + Removal Example: List<String> item...