ReviseAlgo Logo

Spring Fundamentals

What is the Spring Framework? IoC Container Explained

An introduction to Spring, the Inversion of Control paradigm, and the role of the BeanFactory/ApplicationContext.

Interview: A foundational concept that is tested in almost every Java/Spring backend interview to check if you understand how Spring manages object lifecycles.

Last Updated: June 14, 2026 15 min read

Introduction

In standard Java applications, when one object needs another to function (a dependency), it instantiates it directly using the new keyword. This couples classes tightly and makes testing difficult.

The Spring Framework solves this by implementing the Inversion of Control (IoC) paradigm. Instead of your classes creating their own dependencies, control is inverted: an external entity (the IoC Container) instantiates, configures, and manages all application objects (called "Beans") and injects them where needed.

Why It Matters

IoC drastically decouples components. It makes code modular, extensible, and extremely easy to unit test using mock dependencies.

Real-World Analogy

Think of Spring's IoC container like a professional general contractor on a construction site. Instead of the plumber, electrician, and carpenter hiring each other and trying to manage building supplies themselves, the general contractor (IoC container) manages and supplies all workers (beans) and coordinates their dependencies.

How It Works

  1. Metadata Definition: You define classes and mark them with stereotype annotations (like @Component or @Service).
  2. Container Bootstrapping: Spring scans the classpath, detects these annotations, and reads their configurations.
  3. Bean Creation: The IoC container instantiates the objects and loads them into its memory registry.
  4. Dependency Injection: Spring inspects constructors and injects references to the required dependencies dynamically.

Internal Architecture

Component Role What Breaks Without It
BeanFactory The root interface providing basic bean management configuration. Spring cannot instantiate or locate beans.
ApplicationContext Advanced container interface adding AOP integration, events publishing, and internationalization. No enterprise features or automatic context loading.

Practical Example

Here is a basic example of Constructor Dependency Injection managed by Spring's IoC container:

What just happened? By marking MessageRepository as @Component and MessageService as @Service, we registered them as beans. Spring automatically instantiates both, satisfies the constructor dependencies of MessageService, and links them.

Quick Quiz

Q1: What is the main purpose of Spring's IoC container?

A) To connect directly to databases.

B) To instantiate, configure, and manage application objects and their dependencies.

C) To execute raw SQL queries.

D) To compile Java files to bytecode.

Answer: B — Spring's IoC container handles the lifecycle and injection of application beans.

Scenario-Based Challenge

Production Scenario:

You are writing unit tests for a service that sends physical emails. Testing the real service sends emails to customers, which is unacceptable. How does Spring Dependency Injection help resolve this?

View Solution

Since the service takes an interface (e.g., EmailProvider) as a dependency rather than a concrete class, you can create a MockEmailProvider implementing the same interface. In your test configurations, you inject the mock provider bean instead of the real one, verifying code behavior without sending actual emails.

Interview Questions

1. Conceptual: What is the difference between BeanFactory and ApplicationContext?

BeanFactory is the basic container interface, using lazy loading for beans. ApplicationContext inherits from BeanFactory and adds advanced capabilities like eager instantiation of singletons, event propagation, Aspect-Oriented Programming (AOP) hooks, and transaction abstractions.

Production Considerations

In production, default to Constructor Injection. Constructor injection ensures that beans are immutable and cannot be instantiated without all mandatory dependencies, preventing runtime NullPointerExceptions.