Inversion of Control and Dependency Injection

The Problem: Tight Coupling

If a class creates its own dependencies with new, it is tightly coupled to them. You cannot swap the implementation (e.g. a fake payment gateway in tests) without editing the class.

class OrderService {
    // OrderService decides which gateway to use. Hard to test, hard to change.
    private final RazorpayGateway gateway = new RazorpayGateway();
}

The Fix: Ask for Dependencies

Dependency Injection (DI): a class declares what it needs (usually in its constructor) and someone else gives it. Inversion of Control (IoC): that "someone else" is the framework. Control over object creation is inverted, from your class to the Spring IoC container (also called the ApplicationContext).

Example

DI in plain Java: OrderService depends on an interface, and main (playing the role of Spring) decides which implementation to inject.

public class Main {
    public static void main(String[] args) {
        // "the container": creates objects and wires them together
        OrderService prod = new OrderService(new RazorpayGateway());
        OrderService test = new OrderService(new FakeGateway());

        prod.placeOrder(101, 2998);
        test.placeOrder(102, 499);
    }
}

interface PaymentGateway {
    String charge(long orderId, int amount);
}

class RazorpayGateway implements PaymentGateway {
    public String charge(long orderId, int amount) { return "Razorpay charged Rs." + amount + " for order " + orderId; }
}

class FakeGateway implements PaymentGateway {
    public String charge(long orderId, int amount) { return "FAKE payment ok for order " + orderId + " (no money moved)"; }
}

class OrderService {
    private final PaymentGateway gateway;          // depends on the interface only

    OrderService(PaymentGateway gateway) {         // dependency is injected
        this.gateway = gateway;
    }

    void placeOrder(long orderId, int amount) {
        System.out.println(gateway.charge(orderId, amount));
    }
}

Output

Razorpay charged Rs.2998 for order 101
FAKE payment ok for order 102 (no money moved)

What Spring Adds

Your classes (@Component, @Service ...)      Configuration (@Bean, properties)
                     \                              /
                      v                            v
               +-------------------------------------------+
               |   Spring IoC container (ApplicationContext)|
               |   1. finds classes   2. creates beans      |
               |   3. injects dependencies  4. manages life |
               +-------------------------------------------+
                                   |
                                   v
                     ready-to-use, wired objects (beans)

An object created and managed by Spring is called a bean. Benefits: loose coupling, easy testing with mocks, one place to configure, and features like transactions and security can be added around beans automatically.