Spring IoC and Dependency Injection Interview Questions and Answers

Master Spring IoC and Dependency Injection with interview questions covering IoC Container, Dependency Injection, constructor injection, setter injection, field injection, @Autowired, @Qualifier, @Primary, circular dependencies, and production best practices.


Introduction

The core philosophy of the Spring Framework is Inversion of Control (IoC) and Dependency Injection (DI).

Before Spring, applications created objects manually using the new keyword. As applications grew larger, this resulted in:

  • Tight coupling
  • Difficult testing
  • Complex object creation
  • Poor maintainability
  • Difficult configuration management

Spring solves these problems by allowing the IoC Container to create, configure, and inject objects automatically.

Almost every Spring module—including Spring Boot, Spring MVC, Spring Security, Spring Data JPA, and Spring Cloud—depends on IoC and DI.


IoC and DI Architecture

flowchart LR

Application --> SpringContainer

SpringContainer --> CustomerController

SpringContainer --> CustomerService

SpringContainer --> CustomerRepository

CustomerController --> CustomerService

CustomerService --> CustomerRepository

Q1. What is Inversion of Control (IoC)?

Answer

Inversion of Control (IoC) is a design principle in which the responsibility of creating and managing objects is transferred from the application to the Spring IoC Container.

Without IoC

  • Application creates objects.

With IoC

  • Spring creates objects.
  • Spring injects dependencies.
  • Spring manages lifecycle.

Benefits

  • Loose coupling
  • Better maintainability
  • Easier testing
  • Centralized object management

Q2. What is Dependency Injection (DI)?

Dependency Injection is the process of supplying required dependencies to an object instead of allowing the object to create them.

Without DI

CustomerRepository repository =
new CustomerRepository();

CustomerService service =
new CustomerService(repository);

With DI

@Service

public class CustomerService {

    private final CustomerRepository repository;

    public CustomerService(CustomerRepository repository) {
        this.repository = repository;
    }
}

Spring injects CustomerRepository automatically.


Q3. What is the relationship between IoC and DI?

  • IoC is the design principle.
  • DI is the implementation technique used by Spring to achieve IoC.

Relationship

flowchart TD

IoC --> SpringContainer

SpringContainer --> DependencyInjection

DependencyInjection --> ApplicationBeans

Think of IoC as the goal, and DI as the mechanism.


Q4. What are the types of Dependency Injection?

Spring supports three types.

Type Recommended
Constructor Injection ✅ Yes
Setter Injection Sometimes
Field Injection ❌ Avoid in production

Constructor Injection

@Service

public class PaymentService {

    private final PaymentRepository repository;

    public PaymentService(PaymentRepository repository) {
        this.repository = repository;
    }
}

Setter Injection

@Autowired

public void setRepository(

PaymentRepository repository){

}

Field Injection

@Autowired

private PaymentRepository repository;

Although simple, field injection is discouraged for production applications.


Q5. Why is Constructor Injection recommended?

Advantages

  • Immutable dependencies
  • Easier unit testing
  • Mandatory dependencies enforced
  • Better readability
  • No reflection required

Spring recommends constructor injection for most enterprise applications.


Q6. What is @Autowired?

@Autowired instructs Spring to automatically inject a matching bean.

Example

@Autowired

private CustomerService

customerService;

Spring searches the IoC container for a compatible bean and injects it automatically.

From Spring 4.3 onward, if a class has a single constructor, @Autowired on the constructor is optional.


Q7. What are @Qualifier and @Primary?

When multiple beans of the same type exist, Spring cannot determine which bean to inject.

@Primary

Marks the default bean.

@Primary

@Component

class VisaPayment{

}

@Qualifier

Selects a specific bean.

@Autowired

@Qualifier("paypalPayment")

PaymentService service;

Bean Selection

flowchart LR

PaymentInterface --> VisaBean

PaymentInterface --> MasterBean

MasterBean --> Primary

VisaBean --> Qualifier

Q8. What is Circular Dependency?

A circular dependency occurs when two or more beans depend on each other.

Example

Service A

↓

Service B

↓

Service A

Circular Dependency

flowchart LR

ServiceA --> ServiceB

ServiceB --> ServiceA

Constructor-based circular dependencies result in application startup failure.

Solutions

  • Redesign the dependency
  • Introduce an intermediary service
  • Use @Lazy only when absolutely necessary

Q9. What is Loose Coupling?

Loose coupling means classes depend on abstractions, not concrete implementations.

Example

interface PaymentProcessor{

}

Implementations

  • Credit Card
  • UPI
  • PayPal

The service depends only on the interface.

Benefits

  • Easier testing
  • Better extensibility
  • Cleaner architecture

Q10. IoC and DI Best Practices

Prefer Constructor Injection

Avoid field injection.


Depend on Interfaces

Program to abstractions.


Keep Beans Stateless

Improve scalability.


Avoid Circular Dependencies

Refactor instead of using workarounds.


Use @Qualifier Only When Needed

Use @Primary for the default implementation.


Banking Example

flowchart TD

CustomerController --> CustomerService

CustomerService --> PaymentProcessor

PaymentProcessor --> VisaProcessor

PaymentProcessor --> UpiProcessor

VisaProcessor --> BankAPI

UpiProcessor --> UpiGateway

SpringContainer --> CustomerController

SpringContainer --> CustomerService

SpringContainer --> VisaProcessor

SpringContainer --> UpiProcessor

Spring injects the appropriate implementation based on configuration.


Common Interview Questions

  • What is IoC?
  • What is Dependency Injection?
  • IoC vs Dependency Injection?
  • Types of Dependency Injection?
  • Constructor vs Setter Injection?
  • Why avoid Field Injection?
  • What is @Autowired?
  • What are @Qualifier and @Primary?
  • What is Circular Dependency?
  • Why is Constructor Injection recommended?

Quick Revision

Topic Summary
IoC Spring manages object creation
Dependency Injection Inject required dependencies
Constructor Injection Recommended approach
Setter Injection Optional dependencies
Field Injection Avoid in production
@Autowired Automatic dependency injection
@Qualifier Select specific bean
@Primary Default bean
Loose Coupling Depend on interfaces
Circular Dependency Mutual bean dependency

Dependency Injection Lifecycle

sequenceDiagram
Application->>Spring Container: Start
Spring Container->>CustomerRepository: Create Bean
Spring Container->>CustomerService: Create Bean
Spring Container->>CustomerService: Inject Repository
Spring Container->>CustomerController: Create Bean
Spring Container->>CustomerController: Inject Service
Spring Container-->>Application: Ready

Production Example – Banking Payment Platform

A banking application supports multiple payment methods:

  • Credit Card
  • UPI
  • Net Banking

The PaymentService depends only on the PaymentProcessor interface.

During startup:

  • Spring scans all components.
  • It creates beans for each payment implementation.
  • @Primary identifies the default processor.
  • @Qualifier can inject a specific implementation when needed.
  • Constructor injection ensures all required dependencies are available before the application starts.
flowchart LR

SpringContainer --> PaymentService

SpringContainer --> CreditCardProcessor

SpringContainer --> UpiProcessor

SpringContainer --> NetBankingProcessor

PaymentService --> PaymentProcessor

PaymentProcessor --> CreditCardProcessor

PaymentProcessor --> UpiProcessor

PaymentProcessor --> NetBankingProcessor

This design promotes loose coupling, simplifies testing with mock implementations, and makes it easy to introduce new payment methods without modifying existing business logic.


Key Takeaways

  • Inversion of Control (IoC) transfers object creation and lifecycle management from the application to the Spring Container.
  • Dependency Injection (DI) is the mechanism Spring uses to implement IoC by automatically supplying required dependencies.
  • Constructor Injection is the recommended approach because it supports immutability, mandatory dependencies, and easier testing.
  • Setter Injection is suitable for optional dependencies, while Field Injection should generally be avoided in production code.
  • @Autowired automatically injects matching beans from the Spring IoC Container.
  • Use @Primary to define a default implementation and @Qualifier when multiple implementations of the same interface exist.
  • Avoid circular dependencies through better design rather than relying on @Lazy.
  • Following IoC and DI best practices results in modular, testable, maintainable, and enterprise-ready Spring applications.