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:
However, when Spring creates it, it becomes a Spring Bean:
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):
With Spring (Automatic Management):
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:
AnnotationConfigApplicationContextClassPathXmlApplicationContextWebApplicationContext
In Spring Boot, the ApplicationContext is automatically created for you.
Internal Startup Flow
3. What is a Bean Definition?
Before creating an actual object, Spring parses your class and creates metadata.
Spring translates this into metadata called a BeanDefinition:
- Bean Name:
employeeService - Class:
EmployeeService - Scope: Singleton
- Dependencies:
EmployeeRepository
Internal Flow of Metadata
4. The Bean Creation Process
Let's look at exactly how Spring creates a bean internally in 5 steps:
- Scan Package:
@ComponentScandetects the class. - Create BeanDefinition: Spring creates metadata.
- Register Metadata: Registers the definition into the
BeanDefinitionRegistry. - Instantiate Object: Spring creates the actual object using Reflection.
Class<?> clazz = EmployeeService.class; Object obj = clazz.getDeclaredConstructor().newInstance();
- Store in Cache: Stores the bean inside the singleton cache (
singletonObjectsinsideDefaultSingletonBeanRegistry).
The Internal Cache Structure
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):
With DI (Loosely coupled):
6. Types of Dependency Injection
1. Constructor Injection (Recommended)
The safest and most modern approach. Ensures immutable dependencies.
Flow: Create Repository Bean → Create Service Bean → Pass Repository → Constructor Injection.
2. Setter Injection
3. Field Injection (Not Recommended)
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.
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.
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.
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
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:
@Componentis for automatic bean creation via scanning.@Beanis for manual bean creation via a method inside a@Configurationclass. - @Service vs @Repository vs @Component: All are Spring beans based on
@Component.@Servicesignifies business logic.@Repositorysignifies data access and adds exception translation. - @Controller vs @RestController:
@Controllerreturns a View (JSP/HTML).@RestControllerreturns 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:
ApplicationContextBeanFactoryBeanDefinitionBeanDefinitionRegistryClassPathBeanDefinitionScannerDefaultListableBeanFactoryDefaultSingletonBeanRegistryAutowiredAnnotationBeanPostProcessorConfigurationClassPostProcessor
Comments
Post a Comment