How Does ApplicationContext Create Beans in Spring?

A Deep Dive into ApplicationContext
and the Bean Lifecycle
“Don’t just use annotations—understand the architecture.”
1. Why You Should Care
Many Java developers can sprinkle @Autowired
and @Bean
everywhere—but very few truly grasp what happens under the hood. If you only know “how” to use Spring and not “why” it works that way, you’re building on sand. In this article, we’ll reconstruct Spring’s bean-creation process step by step, so you can:
- Go beyond CRUD and speak the language of framework authors.
- Debug Spring source code with confidence.
- Move from “annotation user” to “architecture thinker.”
2. The Single Line That Changes Everything
ApplicationContext ctx = new AnnotationConfigApplicationContext(AppConfig.class);
`
That one line kicks off an orchestration of scanners, processors, and factories. Let’s unpack it.
3. The Full Bean-Creation Workflow
3.1. Parse Configuration & Register Bean Definitions
Scan for Annotations Spring uses
ConfigurationClassPostProcessor
(and friends) to locate:@Configuration
classes@Component
,@Service
,@Repository
@Bean
methods
Generate
BeanDefinition
Objects Each discovered component becomes aBeanDefinition
, capturing:Bean class or factory method
Scope (
singleton
,prototype
, etc.)Dependencies, lazy flags, custom init/destroy methods
Store in BeanFactory Registry All
BeanDefinition
s live in an internal registry insideDefaultListableBeanFactory
.
3.2. Refresh the Context
Calling refresh()
on AnnotationConfigApplicationContext
triggers:
invokeBeanFactoryPostProcessors()
- Allows code to modify or add definitions before beans are created (e.g.
@PropertySource
, custom post-processors).
- Allows code to modify or add definitions before beans are created (e.g.
registerBeanPostProcessors()
- Registers
BeanPostProcessor
instances (e.g. for AOP proxies,@Transactional
).
- Registers
finishBeanFactoryInitialization()
- Pre-instantiates all singleton beans by calling
getBean()
on each definition.
- Pre-instantiates all singleton beans by calling
3.3. Instantiate Beans (createBean()
)
When getBean(name)
is invoked (during refresh or by client code), Spring runs AbstractAutowireCapableBeanFactory#createBean()
:
Instantiate
Choose constructor or factory method
Use reflection to invoke it
Populate Properties
- Inject dependencies via field, setter, or constructor injection (
@Autowired
,@Value
)
- Inject dependencies via field, setter, or constructor injection (
Apply Initialization Callbacks
Methods annotated
@PostConstruct
Interfaces like
InitializingBean.afterPropertiesSet()
Custom
init-method
Invoke
BeanPostProcessor
HookspostProcessBeforeInitialization()
AOP proxies are often created here
postProcessAfterInitialization()
Return Fully Initialized Instance
3.4. Cache Singleton Beans
Singleton Cache (Level 1) holds fully initialized beans.
Early-Reference Cache (Level 2) and Factory Cache (Level 3) handle circular dependencies.
4. Visual Summary
@Configuration + @ComponentScan
↓
parse to BeanDefinition
↓
register in BeanFactory
↓
ctx.refresh()
↓
invokeBeanFactoryPostProcessors()
↓
registerBeanPostProcessors()
↓
finishBeanFactoryInitialization()
↓
for each bean:
getBean() → createBean()
↓
- instantiate (reflection)
- inject dependencies
- initialize callbacks
- apply post processors (AOP)
↓
put into singleton cache
5. What You’ll Gain
Clarity on why Spring chooses proxy-based AOP.
Ability to debug container start-up and bean wiring without panic.
Confidence to extend Spring (custom scopes, processors).
A solid foundation for teaching, architecting, or contributing to framework code.
6. Next Steps: How to Solidify Your Knowledge
Set Breakpoints in Your IDE
In
AnnotationConfigApplicationContext.refresh()
Step through to
DefaultListableBeanFactory.preInstantiateSingletons()
and intocreateBean()
.
Write Your Own Mini-Container
Support: class scanning, simple dependency injection via reflection.
Compare your code with Spring’s implementation.
Blog or Teach
Draft your own article or internal talk.
Explaining concepts to others is the fastest way to master them.
Deepen Related Topics
Read “Java Concurrency in Practice” for thread safety in bean creation.
Explore the “Spring Framework Reference” on custom
BeanPostProcessor
and scopes.
Daily Micro-Challenges
Pick one method (e.g.,
postProcessAfterInitialization
) each day.Trace its call graph and write a one-paragraph summary.
Subscribe to my newsletter
Read articles from Liu yu directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
