Dependency Injection

Loading concept...

Spring Core: Dependency Injection 🌱

The Pizza Shop Story 🍕

Imagine you own a pizza shop. Every day, you need ingredients: cheese, tomato sauce, dough, and toppings.

The Old Way (No DI): You wake up at 4 AM. Drive to the farm for cheese. Go to another farm for tomatoes. Mill your own flour. Exhausting! You’re doing EVERYTHING yourself.

The Smart Way (With DI): Suppliers DELIVER everything to your door. You just focus on making amazing pizzas!

This is Dependency Injection. Someone else gives you what you need. You don’t fetch it yourself.


What is Dependency Injection? 🎁

Think of it like this:

Without DI: “I’ll build my own toys!” With DI: “Mom gives me the toys I need.”

Your class (the child) doesn’t create what it needs. Spring (the parent) provides it.

// WITHOUT DI - Making your own toy
class Child {
    Toy toy = new Toy(); // Hard work!
}

// WITH DI - Getting toys delivered
class Child {
    Toy toy; // Spring gives this!
}

The Three Ways to Get Deliveries 📦

Spring can deliver dependencies in THREE ways. Like three different delivery methods!

1. Constructor Injection (The Moving Truck)

When you move to a new house, the truck brings EVERYTHING at once. You can’t live there without furniture!

@Service
class PizzaShop {
    private final CheeseSupplier cheese;

    // Everything arrives when
    // shop is built!
    public PizzaShop(CheeseSupplier cheese) {
        this.cheese = cheese;
    }
}

Best for: Things you MUST have. No cheese? No pizza shop!

2. Setter Injection (Package Delivery)

Like getting packages after you’ve moved in. Nice to have, but not urgent.

@Service
class PizzaShop {
    private ToppingSupplier toppings;

    // Delivered later, when ready
    @Autowired
    public void setToppings(ToppingSupplier t) {
        this.toppings = t;
    }
}

Best for: Optional things. No extra toppings? Shop still works!

3. Field Injection (Magic Appearance)

Items just appear in your room. Like magic! Simple but mysterious.

@Service
class PizzaShop {
    @Autowired  // Poof! It appears!
    private CheeseSupplier cheese;
}

Warning: Looks easy but harder to test. Use sparingly!

graph TD A[Dependency Injection Types] --> B[Constructor] A --> C[Setter] A --> D[Field] B --> E[Required items] C --> F[Optional items] D --> G[Quick but risky]

@Autowired: The Magic Word 🪄

@Autowired is like saying “Please deliver this!”

Spring hears you and finds the right thing to deliver.

@Service
class Kitchen {
    @Autowired
    private Oven oven;
    // Spring finds an Oven and delivers it!
}

Where Can You Use @Autowired?

Location Example When to Use
Field @Autowired Oven oven Quick setup
Constructor On constructor method Required deps
Setter On setter method Optional deps

Pro Tip: With ONE constructor, @Autowired is optional! Spring is smart.

@Service
class Kitchen {
    private final Oven oven;

    // No @Autowired needed!
    public Kitchen(Oven oven) {
        this.oven = oven;
    }
}

@Qualifier: Choosing Your Supplier 🏷️

What if you have TWO cheese suppliers? Spring gets confused!

@Component
class MozzarellaSupplier implements CheeseSupplier {}

@Component
class CheddarSupplier implements CheeseSupplier {}

Problem: “Which cheese do I deliver?”

Solution: Use @Qualifier to pick one!

@Service
class PizzaShop {
    @Autowired
    @Qualifier("mozzarellaSupplier")
    private CheeseSupplier cheese;
    // Now Spring knows: Mozzarella please!
}

It’s like saying: “I want the RED package, not the blue one!”


@Primary: The Default Choice ⭐

Don’t want to pick every time? Mark one as the favorite!

@Component
@Primary  // I'm the default!
class MozzarellaSupplier implements CheeseSupplier {}

@Component
class CheddarSupplier implements CheeseSupplier {}

Now Mozzarella is always delivered unless you specifically ask for something else.

graph TD A[Multiple Beans?] --> B{Need specific one?} B -->|Yes| C[@Qualifier] B -->|No| D[@Primary] C --> E[Pick exact bean] D --> F[Use default bean]

@Primary vs @Qualifier

Feature @Primary @Qualifier
Where On the bean On injection point
Purpose Set default Pick specific
Override Yes, by @Qualifier N/A

@Value: Reading the Menu 📋

Sometimes you need settings from a file. Like reading today’s prices from a menu!

application.properties:

pizza.price=12.99
shop.name=Mario's Pizza
shop.open=true

Using @Value:

@Service
class PizzaShop {
    @Value("${pizza.price}")
    private double price;

    @Value("${shop.name}")
    private String name;

    @Value("${shop.open}")
    private boolean isOpen;
}

Default Values (Safety Net)

What if a setting is missing? Provide a backup!

@Value("${pizza.price:9.99}")
private double price;
// If not found, use 9.99

SpEL (Spring Expression Language)

Do math or logic right in the annotation!

@Value("#{${pizza.price} * 1.1}")
private double priceWithTax;
// Calculates price + 10% tax

@Value("#{'${shop.name}'.toUpperCase()}")
private String upperName;
// MARIO'S PIZZA

Circular Dependency: The Chicken-Egg Problem 🐔🥚

Imagine this disaster:

  • CheeseSupplier says: “I need PizzaShop to know where to deliver!”
  • PizzaShop says: “I need CheeseSupplier to make pizza!”

Who gets created first? NOBODY! They’re stuck waiting for each other.

@Service
class CheeseSupplier {
    @Autowired
    private PizzaShop shop; // Needs shop!
}

@Service
class PizzaShop {
    @Autowired
    private CheeseSupplier cheese; // Needs cheese!
}

BOOM! Spring crashes with BeanCurrentlyInCreationException

graph LR A[CheeseSupplier] -->|needs| B[PizzaShop] B -->|needs| A style A fill:#ff6b6b style B fill:#ff6b6b

How to Fix Circular Dependencies

Solution 1: Use @Lazy

Tell one bean to wait. “I’ll get you later!”

@Service
class PizzaShop {
    @Autowired
    @Lazy  // Don't get cheese NOW
    private CheeseSupplier cheese;
}

Solution 2: Setter Injection

Let one bean finish first, then connect.

@Service
class CheeseSupplier {
    private PizzaShop shop;

    @Autowired
    public void setShop(PizzaShop shop) {
        this.shop = shop;
    }
}

Solution 3: Redesign (Best!)

If A needs B and B needs A… maybe they should be ONE thing? Or use a third class!

graph TD A[Circular Dependency?] --> B[Try @Lazy] A --> C[Try Setter Injection] A --> D[Redesign Classes] D --> E[Best Solution!] style E fill:#4caf50

Summary: Your DI Toolkit 🧰

Tool Purpose Example
Constructor DI Required deps public Shop(Cheese c)
Setter DI Optional deps setToppings(Topping t)
Field DI Quick but risky @Autowired Oven oven
@Autowired Auto-deliver Marks injection point
@Qualifier Pick specific bean @Qualifier("cheddar")
@Primary Set default bean Mark preferred impl
@Value Read properties @Value("${price}")
@Lazy Break cycles Delay loading

The Big Picture 🖼️

graph TD A[Your Class] --> B[Needs Dependencies] B --> C{How many options?} C -->|One| D[Just @Autowired] C -->|Multiple| E{Need specific?} E -->|Yes| F[@Qualifier] E -->|No| G[@Primary] B --> H{From config?} H -->|Yes| I[@Value]

Remember This! 💡

  1. DI = Getting deliveries instead of fetching yourself
  2. Constructor injection for MUST-HAVE items
  3. @Qualifier picks, @Primary sets default
  4. @Value reads from config files
  5. Circular deps = redesign your code!

You’re now ready to let Spring do the heavy lifting. Focus on your business logic, and let the framework handle the wiring!

Happy Coding! 🚀

Loading story...

No Story Available

This concept doesn't have a story yet.

Story Preview

Story - Premium Content

Please sign in to view this concept and start learning.

Upgrade to Premium to unlock full access to all content.

Interactive Preview

Interactive - Premium Content

Please sign in to view this concept and start learning.

Upgrade to Premium to unlock full access to all content.

No Interactive Content

This concept doesn't have interactive content yet.

Cheatsheet Preview

Cheatsheet - Premium Content

Please sign in to view this concept and start learning.

Upgrade to Premium to unlock full access to all content.

No Cheatsheet Available

This concept doesn't have a cheatsheet yet.

Quiz Preview

Quiz - Premium Content

Please sign in to view this concept and start learning.

Upgrade to Premium to unlock full access to all content.

No Quiz Available

This concept doesn't have a quiz yet.