Loading
Dependency injection-tutorial
The Spring Framework is one of the most popular Java frameworks for building modern, scalable, and maintainable applications.
At the heart of Spring lies two core concepts:

  • Inversion of Control (IoC)
  • Dependency Injection (DI)
Understanding these concepts is essential for mastering Spring development.
This article breaks them down with examples, analogies, and simple explanations.


Why IoC and DI Matter

Before Spring existed, Java applications were often filled with code like this:

class A {
    private B b = new B();
}


Here, class A is directly creating instance B.
This causes:

  • Tight coupling
  • Hard to test (you cannot easily substitute mock objects)
  • Poor maintainability
  • Difficult configuration changes
Spring solves this entire problem.



What is Inversion of Control (IoC) ?

Inversion of Control means
You don not create objects manually.
The Spring Ioc Container creates and manages them for you.
Traditionally, your code controls object creation using new.
With IoC, that control is inverted Spring handles it.


Real world Analogy

Imagine eating in a restaurant.
You don not cook your food.
You simply order, and the kitchen takes care of preparation.
Similarly, instead of creating objects, you request them from Spring.



What is Dependency Injection (DI) ?

Dependency Injection is how Spring implements IoC.
A dependency is just another object that a class needs to work.

DI means:
The required dependencies are injected into an object from outside, instead of the object creating them internally.


Example Without DI 

class A {
    private B b = new B();
}

Class A directly controls he creation of B --> tight coupling.


Example With DI

class A {
    private B b;

    public A(B b) {
        this.b = b;
    }
}

Now A does not create B.
it receives B from the outside --> loose coupling.

Spring handles this injection automatically.



Types of Dependency Injection in Spring

Spring provides three main ways to inject dependencies


1. Constructor Injection (Recommended)

@Component
class A {
    private final B b;

    @Autowired
    public A(B b) {
        this.b = b;
    }
}

  • Best for mandatory dependencies
  • Makes classes easier to test
  • Supports immutability


2. Setter Injection

@Component
class A {
    private B b;

    @Autowired
    public void setB(B b) {
        this.b = b;
    }
}

Best for optional or changeable dependencies


3. Field Injectoin (Not Recommended for Production)

@Component
class A {
    @Autowired
    private B b;
}

  • Harder to test
  • No immutability
  • Less clear dependencies
Still useful for quick prototypes or very simple components.



How IoC Container Works in Spring

The IoC Container is the core engine of Spring.
It:

  • Creates objects (called beans)
  • Manages their lifecycle
  • Injects dependencies
  • Handles configurations
  • Ensures loose coupling

Spring container can be configured using:

  • XML configuration
  • Java-based configuration (@Configuration)
  • Annotation-based configuration (@Component, @Autowired)


Spring Bean Creation Flow

  • Application starts
  • Spring scans the project
  • Beans are created
  • Dependencies are injected
  • Beans are stored inside the IoC container
  • Application runs using these managed objects


Benefits of IoC & DI in Spring

  • Loose coupling
  • Better maintainability
  • Easier unit testing
  • Cleaner architecture
  • Reusable components
  • Lower risk of breaking changes
These principles make Spring extremely powerful for enterprise Java applications.


Two Minute Drill

  • Inversion of Control shifts the control of object creation from your applicatoin to the Spring container
  • Dependency Injection provides your classes the objects they need without creating them manually.