HuntExams Academy logo
JavaBeginner#spring

What is Inversion of Control (IoC) in Spring?

Answer

IoC is a principle where object creation and dependency management are delegated to a container (the Spring IoC container) rather than being handled manually by the code, enabling loose coupling and easier testing.

Example

@Component
class EmailService {}
@Component
class NotificationService {
  @Autowired EmailService emailService; // Spring container injects this
}

Detailed explanation

Inversion of Control (IoC) is a design principle in which responsibility for creating and connecting application objects moves from application code to a framework or container. Without IoC, a NotificationService might create its own EmailService using new EmailService(). With Spring IoC, the container creates and manages these objects and supplies the required dependencies. The control being inverted is mainly control over object construction, dependency wiring, and lifecycle management, not the business decisions inside your methods.

Spring’s IoC container manages objects called beans. BeanFactory provides the basic container contract, while ApplicationContext extends it with features such as application events and resource handling and is the usual choice in applications. Bean definitions can come from component scanning, @Bean methods in configuration classes, or XML. During context initialisation, Spring reads these definitions, creates eligible beans, resolves dependencies, and performs configured initialisation callbacks. By default, an ApplicationContext eagerly creates non-lazy singleton beans; other scopes and lazy configuration affect when instances are created.

In the example, @Component makes EmailService and NotificationService candidates for registration when their packages are included in component scanning. The @Autowired field tells Spring to inject a matching EmailService bean after constructing NotificationService. Dependency injection (DI) is the mechanism Spring commonly uses to implement IoC; the terms are related but not identical. Constructor injection is generally preferred because it makes required dependencies explicit and supports final fields. For a class with a single constructor, Spring can inject its parameters without @Autowired. If multiple beans match a dependency, @Qualifier or @Primary can help select one.

IoC matters because classes no longer need to know how their collaborators are constructed or configured. Depending on an interface further reduces coupling and allows implementations to be replaced. In a unit test, constructor injection lets you supply a fake or mock dependency without starting Spring. Interviewers usually expect you to explain who creates the objects, distinguish IoC from DI, and connect the principle to maintainability and testing. Also remember that manually creating a NotificationService with new does not automatically trigger Spring’s dependency injection.

Key points to remember

  • IoC transfers object creation, wiring, and lifecycle management to Spring’s container.
  • Objects registered with and managed by the container are called beans.
  • ApplicationContext is the commonly used Spring IoC container interface.
  • Dependency injection is a mechanism for implementing IoC, not a synonym for the broader principle.
  • Constructor injection makes required dependencies explicit and simplifies unit testing.

Common mistakes candidates make

  • Assuming @Component registers a class even when its package is outside component scanning.
  • Expecting @Autowired injection to happen automatically on an object created manually with new.
  • Claiming IoC eliminates coupling entirely; depending on concrete implementations can still restrict flexibility.

Likely follow-up questions

What is the difference between IoC and dependency injection?

IoC is the broader principle of transferring control from application code to a framework or container. Dependency injection implements this principle by supplying an object’s dependencies externally rather than having the object create them.

Why is constructor injection preferred over field injection?

Constructor injection makes required dependencies visible and allows dependency fields to be final. It also lets a unit test construct the object directly with mocks or fakes, without Spring or reflective field access.

What happens if Spring finds multiple beans of the required type?

If Spring cannot determine a unique candidate for a single-valued dependency, dependency resolution fails, typically with a NoUniqueBeanDefinitionException. Use @Qualifier to identify the intended candidate or @Primary to mark a preferred bean.

Interview tip: Explain who controls object creation, walk through the two beans in the example, and finish with why constructor injection makes testing easier.

Related Interview Questions

1
JavaIntermediate#spring

What are the different types of dependency injection in Spring?

Open
2
JavaBeginner#spring

What is the difference between @Component, @Service, @Repository, and @Controller?

Open
3
JavaIntermediate#spring

What is Spring Boot auto-configuration?

Open