Dependency Injection & Bean Creation Deep Dive

Author Avatar
Learn Here Fun Pedia
5 min read •

Dependency Injection & Bean Creation Deep Dive

To truly master the Spring Framework and Spring Boot, you must understand exactly how it manages objects, resolves dependencies, and orchestrates its internal startup flow. Let's break down the core architectural concepts of Dependency Injection and Bean Creation.


1. What is a Bean?

Standard Definition

A Bean is an object that is created, managed, configured, and destroyed by the Spring IOC Container.

Consider a standard Java object:

public class EmployeeService { } // Normal Java Object (NOT a Spring Bean) EmployeeService service = new EmployeeService();

However, when Spring creates it, it becomes a Spring Bean:

@Service public class EmployeeService { }

What does "Managed by Spring" mean?

When an object is managed by Spring, the framework automatically handles:

  • Object Creation
  • Dependency Injection
  • Initialization
  • Configuration
  • Lifecycle Management
  • Destruction

Without Spring (Manual Creation):

EmployeeRepository repo = new EmployeeRepository(); EmployeeService service = new EmployeeService(repo);

With Spring (Automatic Management):

@Service public class EmployeeService { private final EmployeeRepository repo; public EmployeeService(EmployeeRepository repo) { this.repo = repo; } }

Spring automatically creates both objects and wires them together.


2. What is the IOC Container?

IOC stands for Inversion of Control.

In traditional Java, the developer controls object creation (using the new keyword). In Spring, the framework creates the objects. Control moves from the Developer → Spring. Hence, "Inversion of Control."

IOC Container Internals

The main container interface is the ApplicationContext. Some concrete implementations include:

  • AnnotationConfigApplicationContext
  • ClassPathXmlApplicationContext
  • WebApplicationContext

In Spring Boot, the ApplicationContext is automatically created for you.

Internal Startup Flow

SpringApplication.run() | V Create ApplicationContext | V Component Scan | V Find Bean Classes | V Create Bean Definitions | V Register Bean Definitions | V Instantiate Beans | V Inject Dependencies | V Store Beans in IOC Container | V Application Ready

3. What is a Bean Definition?

Before creating an actual object, Spring parses your class and creates metadata.

@Service public class EmployeeService { }

Spring translates this into metadata called a BeanDefinition:

  • Bean Name: employeeService
  • Class: EmployeeService
  • Scope: Singleton
  • Dependencies: EmployeeRepository

Internal Flow of Metadata

@Component | V ClassPath Scanner | V BeanDefinition | V BeanFactory | V Object Creation

4. The Bean Creation Process

Let's look at exactly how Spring creates a bean internally in 5 steps:

  1. Scan Package: @ComponentScan detects the class.
  2. Create BeanDefinition: Spring creates metadata.
  3. Register Metadata: Registers the definition into the BeanDefinitionRegistry.
  4. Instantiate Object: Spring creates the actual object using Reflection.
    Class<?> clazz = EmployeeService.class; Object obj = clazz.getDeclaredConstructor().newInstance();
  5. Store in Cache: Stores the bean inside the singleton cache (singletonObjects inside DefaultSingletonBeanRegistry).

The Internal Cache Structure

singletonObjects | +---- employeeService | +---- employeeRepository | +---- dataSource

5. What is Dependency Injection?

Standard Definition

Dependency Injection is a design pattern where Spring provides required dependencies to an object instead of the object creating them itself.

Without DI (Tightly coupled):

public class EmployeeService { EmployeeRepository repo = new EmployeeRepository(); }

With DI (Loosely coupled):

public class EmployeeService { private EmployeeRepository repo; public EmployeeService(EmployeeRepository repo) { this.repo = repo; } }

6. Types of Dependency Injection

1. Constructor Injection (Recommended)

The safest and most modern approach. Ensures immutable dependencies.

@Service public class EmployeeService { private final EmployeeRepository repo; public EmployeeService(EmployeeRepository repo) { this.repo = repo; } }

Flow: Create Repository Bean → Create Service Bean → Pass Repository → Constructor Injection.

2. Setter Injection

@Autowired public void setRepo(EmployeeRepository repo) { this.repo = repo; }

3. Field Injection (Not Recommended)

@Autowired private EmployeeRepository repo;

7. How Dependency Injection Works Internally

When Spring creates EmployeeService, it sees that EmployeeRepository is required. It searches the IOC container. If found, it injects it.

Create EmployeeRepository | V Store in Container | V Create EmployeeService | V Need Repository? | V Get Bean from Container | V Inject Dependency

8. Deep Dive into Stereotype Annotations

@Component

A generic Spring Bean. Internally, it triggers the ClassPathBeanDefinitionScanner to create a BeanDefinition and instantiate the bean.

@Service

A specialized @Component representing the Business Logic Layer. Internally, @Service is meta-annotated with @Component. It carries semantic meaning for developers.

@Repository

Represents the DAO Layer. Internally, it is also a @Component, but it provides a massive extra feature: Exception Translation.

If the database throws a raw SQLException, the PersistenceExceptionTranslationPostProcessor catches it at the repository layer and translates it into Spring's database-independent DataAccessException hierarchy.

@Controller

Used in Spring MVC. It specifically returns a View Name, which is processed by the ViewResolver to return JSP or HTML.

@RestController

Used for REST APIs. It returns raw data (JSON) directly to the response body.

Internally, @RestController = @Controller + @ResponseBody.

Request -> Controller -> Java Object -> Jackson -> JSON -> Response

9. Java Configuration: @Configuration & @Bean

Before Spring Boot, everything was configured via XML (<bean id="employeeService"/>). Modern Spring uses Java Configuration.

@Configuration

Marks a class as a configuration source containing bean definitions. Internally, it is meta-annotated with @Component, allowing Spring to detect it during a component scan.

@Bean

Used to create beans manually. Spring registers the returned object as a bean in the container.

@Configuration public class AppConfig { @Bean public EmployeeService employeeService() { return new EmployeeService(); } }

Why is @Bean needed?
If a class belongs to a third-party library (e.g., PaymentGateway), you cannot modify its source code to add @Component. You must use @Bean to instantiate and configure it manually.


10. @Component vs @Bean (Interview Favorite)

Feature @Component @Bean
Applied On Class Method
Bean Creation Automatic Manual
Scanning Required Yes No
Third Party Class No Yes
Uses Component Scan Yes No
Control Level Less More (Custom Initialization)

When to use @Component? When you own the source code (Service, DAO, Controller utility classes).

When to use @Bean? For third-party library classes, custom initialization logic, or creating multiple bean instances.


11. Complete Internal Flow of Dependency Injection

SpringApplication.run() | V ApplicationContext Created | V @ComponentScan | V Find Classes | V Create BeanDefinition | V Register BeanDefinition | V Instantiate Beans | V Constructor Dependency Analysis | V Find Required Beans | V Resolve Dependencies | V Inject Dependencies | V Store Beans in Singleton Cache | V Application Ready

12. Interview Summary & Key Takeaways

Core Concepts

  • What is Dependency Injection? A mechanism where Spring provides required dependencies to an object instead of the object creating them manually.
  • What is a Bean? An object created, managed, and maintained by the Spring IOC Container.
  • @Component vs @Bean: @Component is for automatic bean creation via scanning. @Bean is for manual bean creation via a method inside a @Configuration class.
  • @Service vs @Repository vs @Component: All are Spring beans based on @Component. @Service signifies business logic. @Repository signifies data access and adds exception translation.
  • @Controller vs @RestController: @Controller returns a View (JSP/HTML). @RestController returns raw data (JSON/XML) directly.
  • Why Constructor Injection? It ensures immutable dependencies, makes unit testing easier, prevents NullPointerExceptions, and is officially recommended by the Spring team.

Internal Classes You Must Know

To demonstrate a senior-level understanding, familiarize yourself with these backend classes:

  • ApplicationContext
  • BeanFactory
  • BeanDefinition
  • BeanDefinitionRegistry
  • ClassPathBeanDefinitionScanner
  • DefaultListableBeanFactory
  • DefaultSingletonBeanRegistry
  • AutowiredAnnotationBeanPostProcessor
  • ConfigurationClassPostProcessor

Comments (0)