juniorSpring

What is Dependency Injection in Spring, and why is it important?

Updated Feb 20, 2026

Short answer

Dependency Injection is a design pattern where Spring creates and provides an object's dependencies instead of the object creating them itself. It reduces coupling, improves testability, and makes applications easier to maintain because classes focus on their responsibilities rather than object creation.

Deep explanation

What Dependency Injection means

In traditional code, a class often creates the objects it needs:

WithoutDependencyInjection.java
class OrderService {
private PaymentService paymentService = new PaymentService();
}

The OrderService is tightly coupled to PaymentService. If the payment logic changes or you want to use a fake payment service during testing, the class must be modified.

With Dependency Injection, the responsibility of creating and connecting objects moves to the Spring container. The class simply declares what it needs, and Spring supplies it.

The key idea: objects receive their dependencies from outside instead of creating them internally.

How Spring performs Dependency Injection

Spring uses an IoC (Inversion of Control) container to manage application objects called beans. A bean is an object created, configured, and managed by Spring.

Common ways to inject dependencies:

Injection typeHow it worksRecommendation
Constructor injectionDependency is provided through a constructorPreferred approach
Setter injectionDependency is provided through a setter methodUseful for optional dependencies
Field injectionDependency is placed directly on a fieldGenerally avoided

A typical example uses constructor injection:

OrderService.java
@Service
class OrderService {
private final PaymentService paymentService;
OrderService(PaymentService paymentService) {
this.paymentService = paymentService;
}
void placeOrder() {
paymentService.processPayment();
}
}

Here, OrderService does not know how PaymentService is created. It only depends on the PaymentService contract.

Dependency flow in Spring

Rendering diagram…

Why Dependency Injection matters

Dependency Injection makes code loosely coupled, which means classes depend on abstractions rather than concrete implementations.

This provides several benefits:

  • Better testing: A real database service can be replaced with a mock implementation during unit tests.
  • Easier maintenance: Changing one implementation does not require rewriting every class that uses it.
  • Reusable components: Services can be shared and configured centrally.
  • Cleaner design: Classes follow the Single Responsibility Principle by avoiding object creation logic.
⚠️ A good rule of thumb: a class should describe what it needs, not how to build what it needs.

Dependency Injection vs creating objects manually

ApproachObject creationCoupling
Manual creation with newClass controls creationHigher
Dependency InjectionContainer controls creationLower

The interviewer is usually checking whether you understand that `Spring` manages object relationships, not just that it automatically creates objects.

Real-world example

Imagine an online shopping application with an OrderService. Today it uses StripePaymentService, but tomorrow the business may switch to another payment provider.

With Dependency Injection, OrderService depends on the PaymentService interface, not a specific provider:

PaymentService.java
interface PaymentService {
void processPayment();
}
@Service
class OrderService {
private final PaymentService paymentService;
OrderService(PaymentService paymentService) {
this.paymentService = paymentService;
}
}

Spring can inject the correct implementation based on configuration. The order logic remains unchanged, even when payment providers change.

Common mistakes

  • * **Field injection** - Using `@Autowired` directly on fields makes testing harder and hides dependencies
  • prefer constructor injection.
  • * **Confusing DI with object creation** - Dependency Injection does not remove objects
  • it moves creation and wiring responsibility to `Spring`.
  • * **Injecting concrete classes everywhere** - Depending on interfaces or abstractions usually creates more flexible designs.
  • * **Overusing dependencies** - A class with too many injected services may have too many responsibilities
  • consider splitting it.

Follow-up questions

  • What is the difference between Dependency Injection and Inversion of Control?
  • Why is constructor injection preferred over field injection in Spring?
  • What happens if Spring finds multiple beans of the same type?
  • What are Spring beans?

More Spring interview questions

View all →