Skip to main content

Command Palette

Search for a command to run...

Java Series #14: Spring IoC, Beans & Spring MVC

Spring IoC, Beans & Spring MVC — Explained Without the Noise

Published
4 min read
Java Series #14: Spring IoC, Beans & Spring MVC
A

I am a Full-stack dev turning ideas into sleek, functional experiences 🚀. I am passionate about AI, intuitive UI/UX, and crafting user-friendly platforms . I am always curious – from building websites to diving into machine learning and under the hood workings ✨. Next.js, Node.js, MongoDB, and Tailwind are my daily tools. I am here to share dev experiments, lessons learned, and the occasional late-night code breakthroughs. Always evolving, always building.

Spring feels confusing only when concepts are learned in isolation.
This article connects IoC, containers, beans, DI, lifecycle, scopes, and finally shows how Spring MVC fits on top of all this — in one clean flow.

1. The Core Problem Spring Solves

Without Spring, you write:

Engine engine = new Engine();
Car car = new Car(engine);

You are responsible for:

  • creating objects

  • wiring dependencies

  • managing lifecycle

This leads to tight coupling and hard-to-maintain code.

2. IoC (Inversion of Control): The Big Idea

You don’t create objects. Spring does.

Spring:

  • creates objects (beans)

  • injects dependencies

  • manages lifecycle

📌 IoC is the principle
📌 Container is the implementation
📌 Bean is the object Spring manages

3. Bean Container vs IoC Container

  • IoC container → concept (who controls object creation?)

  • Bean container → actual Spring container implementation

In Spring, these are practically the same thing.

4. Types of Spring Containers

1️. BeanFactory (Basic)

  • Oldest container

  • Lazy initialization

  • Basic DI support

BeanFactory factory = new XmlBeanFactory(resource);

✅ Lightweight
❌ No events, no i18n, no auto post-processing

Used rarely today.

BeanFactory + enterprise features

Adds:

  • event propagation

  • internationalization (i18n)

  • automatic BeanPostProcessor execution

  • AOP integration

ApplicationContext context =
    new ClassPathXmlApplicationContext("beans.xml");

📌 Used in almost all modern Spring apps

5. Dependency Injection Types

1️. Constructor Injection (Best Practice)

@Component
class Car {
    private final Engine engine;

    @Autowired
    public Car(Engine engine) {
        this.engine = engine;
    }
}
  • mandatory dependencies

  • immutable

  • test-friendly

2️. Setter Injection

@Autowired
public void setEngine(Engine engine) {
    this.engine = engine;
}
  • optional dependencies

  • mutable

3️. Field Injection (Avoid)

@Autowired
private Engine engine;
  • hard to test

  • hides dependencies

6. Autowiring & @Qualifier

Spring injects dependencies by type first.

Problem: Multiple beans of same type

@Component class PetrolEngine implements Engine {}
@Component class DieselEngine implements Engine {}
@Autowired
Engine engine; // ambiguity error

Solution: @Qualifier

@Autowired
@Qualifier("dieselEngine")
private Engine engine;

Key points:

  • resolves ambiguity

  • works with constructor, setter, field

  • injects specific bean by name

  • no match → exception (or null if optional)

7. Bean Lifecycle (Simplified)

Container starts
 → Bean created
 → Dependencies injected
 → Initialization
 → Bean ready
 → Container shuts down
 → Bean destroyed

Lifecycle Hooks

Annotations (preferred):

@PostConstruct
void init() {}

@PreDestroy
void destroy() {}

Other options:

  • XML init-method / destroy-method

  • Interfaces (InitializingBean, DisposableBean)

8. BeanPostProcessor vs BeanFactoryPostProcessor

BeanFactoryPostProcessor

  • runs before beans are created

  • modifies bean definitions

BeanPostProcessor

  • runs after bean creation

  • modifies actual bean instances

  • used in AOP, proxies, security

📌 ApplicationContext handles both automatically.

9. Bean Scopes

ScopeMeaning
singletonone instance per container (default)
prototypenew instance each request
requestone per HTTP request
sessionone per HTTP session
globalSessionlegacy, rarely used

Where Spring MVC Fits ?

Up to now, everything works even without web.
So how do HTTP requests enter the picture?

Spring Core vs Spring MVC

Spring Core

  • IoC container

  • beans

  • DI

  • lifecycle

  • scopes

Spring MVC

  • HTTP handling

  • controllers

  • URL mapping

  • view resolution

📌 Spring MVC runs on top of Spring Core

Controllers are just beans.

DispatcherServlet: The Heart of Spring MVC

Spring MVC answers three questions:

  1. Who receives HTTP requests?

  2. Which controller handles them?

  3. Which view should be returned?

Answer to #1:

DispatcherServlet

Request flow:

Browser
 → DispatcherServlet
 → Controller (bean)
 → Service (bean)
 → Repository (bean)
 → Database

Nothing bypasses IoC.

Controllers Are Normal Beans

@Controller
public class HomeController {

    @GetMapping("/")
    public String home() {
        return "home";
    }
}

Truth:

  • @Controller = @Component

  • lifecycle rules apply

  • DI works the same way

ViewResolver

Controller returns:

return "home";

ViewResolver converts it to:

/WEB-INF/views/home.jsp

This is configuration, not controller logic.

Spring Boot Reality Check

If you use Spring Boot:

  • no web.xml

  • no manual DispatcherServlet config

  • no XML

Spring Boot auto-configures:

  • DispatcherServlet

  • component scanning

  • MVC setup

You focus on business logic only.

Final Mental Model

ApplicationContext
 → creates beans
 → injects dependencies
 → manages lifecycle
 → applies scopes
        ↓
Spring MVC
 → DispatcherServlet
 → Controller beans
 → HTTP handling

Spring doesn’t remove complexity it centralizes and manages it for you.

Spring MVC is a web framework built on top of Spring’s IoC container, where controllers are regular beans managed through dependency injection, lifecycle control, and scopes.