Spring Boot Internals — From Component Scan to Bean Creation (The Complete Guide)
What You'll Learn After reading this guide, you'll clearly understand: What happens after SpringApplication.run() What is an IoC Container? What is ApplicationContext? What is BeanFactory? Why does Spring…
What You’ll Learn
After reading this guide, you’ll clearly understand:
- What happens after
SpringApplication.run() - What is an IoC Container?
- What is
ApplicationContext? - What is
BeanFactory? - Why does Spring use
DefaultListableBeanFactory? - What is Component Scanning?
- What is Bean Definition?
- Difference between Bean Definition and Bean Object
- How Dependency Injection actually happens
- Complete startup flow
- Internal architecture
- Interview Questions
- Memory Tricks
1. Introduction
When beginners start learning Spring Boot, they often hear statements like:
- Spring creates beans.
- Component Scan registers beans.
- ApplicationContext manages beans.
- BeanFactory creates beans.
- IoC Container performs dependency injection.
While these statements are not wrong, they are incomplete.
Many developers use these terms interchangeably, leading to confusion because each component has a distinct responsibility.
To truly understand Spring Boot internals, we need to examine what happens after executing:
SpringApplication.run(DemoApplication.class, args);
At this point, Spring Boot performs hundreds of internal operations, but the bean management process can be broken down into a clear sequence.
2. Why Developers Get Confused
Most tutorials simplify the startup process as:
Component Scan
↓
Creates Beans
This is technically incorrect.
There are actually three separate phases.
Find Classes
↓
Register Bean Definitions
↓
Create Bean Objects
Each phase is performed by different Spring components.
Understanding this distinction is one of the biggest differences between junior and senior Spring developers.
3. The Big Picture
SpringApplication.run()
│
▼
Creates ApplicationContext
│
▼
Starts Component Scanning
│
▼
Discovers Candidate Classes
│
▼
Registers Bean Definitions
│
▼
BeanFactory Creates Bean Objects
│
▼
Dependency Injection
│
▼
Bean Initialization
│
▼
Application Ready
Notice something important.
At no point does Component Scan create objects.
Its only responsibility is discovering classes.
4. Step One – Component Scan
Suppose we have:
@Service
public class UserService {
}
Spring scans packages specified by
@SpringBootApplication
which internally includes
@ComponentScan
Spring now discovers:
UserService
At this moment:
❌ No object exists.
Spring has only found a class that should become a managed bean.
Think of Component Scan as a recruiter finding suitable employees.
The recruiter does not hire or train employees.
It only identifies candidates.
5. Bean Definition
This is one of the least understood concepts in Spring.
After finding the class, Spring creates a Bean Definition.
A Bean Definition is simply metadata describing how to create a bean.
It contains information such as:
- Bean class
- Bean name
- Scope
- Constructor
- Lazy initialization
- Init methods
- Destroy methods
- Autowiring mode
Conceptually:
Bean Definition
Name : userService
Class : UserService
Scope : Singleton
Lazy : false
Notice:
Still no object exists.
The Bean Definition is merely a blueprint.
Think of it like an architectural drawing for a house.
The blueprint exists before construction begins.
6. Where is the Bean Definition Stored?
Many developers think Component Scan stores beans.
Actually, it stores Bean Definitions.
Those Bean Definitions are kept inside the BeanFactory.
ApplicationContext
│
▼
DefaultListableBeanFactory
│
▼
Bean Definition Map
Internally Spring maintains a registry of Bean Definitions.
Each entry tells Spring how to create that bean later.
7. Bean Creation
Once Spring has all Bean Definitions, it begins creating objects.
Now Spring finally executes something equivalent to:
UserService service = new UserService();
Now the bean exists.
Notice the timeline:
Component Scan
↓
Bean Definition
↓
Bean Object
These are three different concepts.
8. Dependency Injection
Suppose UserService depends on UserRepository.
@Service
public class UserRepository {
}
@Service
public class UserService {
private final UserRepository repository;
public UserService(UserRepository repository) {
this.repository = repository;
}
}
Spring first creates
UserRepository
Then creates
UserService(repository)
This process is Dependency Injection.
Spring injects an already-created dependency into another bean instead of the bean creating it itself.
9. Who Actually Creates Beans?
Many developers answer:
“ApplicationContext.”
This answer is only partially correct.
The detailed answer is:
ApplicationContext delegates bean creation to its internal BeanFactory implementation.
10. BeanFactory
BeanFactory is the core IoC container interface.
It defines operations like:
getBean()
containsBean()
isSingleton()
isPrototype()
But because BeanFactory is only an interface, it cannot create objects by itself.
It requires an implementation.
11. DefaultListableBeanFactory
The implementation Spring Boot uses internally is
DefaultListableBeanFactory
Its responsibilities include:
- Storing Bean Definitions
- Creating beans
- Injecting dependencies
- Managing singleton cache
- Resolving
@Autowired - Bean lifecycle management
- Returning beans through
getBean()
Think of it as the engine of the Spring container.
12. ApplicationContext
ApplicationContext is the advanced IoC container.
It does not only manage beans.
It also provides:
- Component scanning
- Event publishing
- Property resolution
- Internationalization
- Resource loading
- Environment abstraction
Internally it contains a BeanFactory.
ApplicationContext
│
▼
DefaultListableBeanFactory
13. Delegation Principle
Spring follows composition instead of making one giant class.
Instead of ApplicationContext doing everything, it delegates specialized tasks.
ApplicationContext
│
├── Component Scanner
├── BeanFactory
├── Environment
├── Event Publisher
└── Resource Loader
Each component has one primary responsibility.
14. Internal Startup Flow
SpringApplication.run()
│
▼
Create ApplicationContext
│
▼
Create DefaultListableBeanFactory
│
▼
Component Scan
│
▼
Discover Classes
│
▼
Create Bean Definitions
│
▼
Store Definitions
│
▼
Create Singleton Beans
│
▼
Dependency Injection
│
▼
@PostConstruct
│
▼
Application Ready
15. Responsibilities Table
| Component | Responsibility |
|---|---|
| SpringApplication | Starts the application |
| ApplicationContext | Coordinates the container |
| Component Scanner | Finds annotated classes |
| BeanFactory | Creates and manages beans |
| DefaultListableBeanFactory | Actual implementation of BeanFactory |
| Bean Definition | Blueprint of a bean |
| Bean Instance | Actual Java object |
| Dependency Injection | Injects dependencies |
| BeanPostProcessor | Customizes beans before and after initialization |
16. Common Misconceptions
❌ Component Scan creates beans.
Correct:
Component Scan only discovers classes and registers Bean Definitions.
❌ Bean Definition is a bean.
Correct:
A Bean Definition is only metadata.
❌ ApplicationContext directly creates beans.
Correct:
ApplicationContext delegates bean creation to DefaultListableBeanFactory.
❌ BeanFactory and ApplicationContext are the same.
Correct:
ApplicationContext extends BeanFactory and adds many enterprise features.
17. Interview Questions
Q1. What is the difference between Component Scan and Bean Creation?
Component Scan discovers classes annotated with Spring stereotypes and registers their Bean Definitions. The IoC container later creates actual bean instances using the registered definitions.
Q2. What is a Bean Definition?
A Bean Definition is metadata describing how a bean should be created, including its class, scope, lifecycle callbacks, constructor, and configuration.
Q3. Why is DefaultListableBeanFactory important?
It is Spring’s default implementation of the BeanFactory interface and is responsible for storing Bean Definitions, creating beans, resolving dependencies, managing bean scopes, lifecycle, and singleton caching.
Q4. What is the relationship between ApplicationContext and BeanFactory?
ApplicationContext extends BeanFactory and delegates bean creation and lifecycle management to an internal DefaultListableBeanFactory while providing additional enterprise features like event publishing, resource loading, property management, and component scanning.
18. Memory Trick
Remember this hierarchy:
IoC
│
▼
IoC Container
│
▼
ApplicationContext
│
▼
DefaultListableBeanFactory
│
▼
Bean Definition
│
▼
Bean Object
A simple way to remember the responsibilities:
- IoC → The design principle (control is inverted).
- IoC Container → The overall concept of a container that manages objects.
- ApplicationContext → The coordinator that manages the Spring application.
- DefaultListableBeanFactory → The engine that creates and manages beans.
- Bean Definition → The blueprint describing how to create a bean.
- Bean Instance → The actual Java object managed by Spring.