Spring 源码分析之 Bean 的全生命周期
约 1032 字大约 3 分钟
2026-05-25
学习源码之前先思考一个问题,我们为什么要学习源码?有什么用?
工作这么多年我总结了以下几点原因
- 第一点:应付面试!现在Java开发人员越来越多,公司的要求也变得越来越高,源码成为我们必不可少的面点!
- 第二点:核心竞争!现在氛围好点的公司中,大家工作中对技术讨论还是比较多的,如果你不懂源码的话就没办法参与到源码这部分的讨论中,更不用说参与一些核心代码的开发工作
- 第三点:学以致用!之前部署一套新Cloud服务的时候,同事遇到Feign调用其他服务报 ClientException 异常的问题,在大家轮番上场都一筹莫展的时候,我运用学习源码时的思路,逐步分析Ribbon源码,最终解决了问题
- 第四点:组件封装!学会源码以后,就可以根据源码扩展出各种组件,是高级开发必备技能
开篇
我在学习Spring源码的过程中略有心得,通过流程图记录下源码执行流程、各种扩展点以及一些自己的理解。

- Spring在启动时会先创建 BeanFactory,默认是ConfigurableListableBeanFactory,
- 通过BeanDefinitionReader解析xml、注解等定义的Bean信息包装成BeanDefinition存到BeanFactory中的BeanDefinitionMap中,
- 然后调用BeanFactoryPostProcessor接口进行扩展,
- 进行实例化前的准备工作:注册BeanPostProcesser、初始化国际化资源、初始化事件多播器、注册监听器。
- 准备完成后对所有非延迟加载的单例进行实例化,通过反射的形式创建对象,进行属性填充,然后进行相应的Aware接口的感知调用,
- 执行BeanPostProcesser的前置处理,在初始化方法调用之后执行BeanPostProcesser的后置处理,
- 此时Bean的对象创建完成
源码的学习,都是从上面的流程学起,面试经常问题的Spring Bean的生命周期,就是上面图中,Bean创建的流程,在BeanFactory中有对应的注释,如下:

在源码中 AbstractApplicationContext #refresh 方法即为Spring Bean完整生命周期的体现
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh");
// Prepare this context for refreshing.
prepareRefresh();
// Tell the subclass to refresh the internal bean factory.
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// Prepare the bean factory for use in this context.
prepareBeanFactory(beanFactory);
try {
// Allows post-processing of the bean factory in context subclasses.
postProcessBeanFactory(beanFactory);
StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process");
// Invoke factory processors registered as beans in the context.
invokeBeanFactoryPostProcessors(beanFactory);
// Register bean processors that intercept bean creation.
registerBeanPostProcessors(beanFactory);
beanPostProcess.end();
// Initialize message source for this context.
initMessageSource();
// Initialize event multicaster for this context.
initApplicationEventMulticaster();
// Initialize other special beans in specific context subclasses.
onRefresh();
// Check for listener beans and register them.
registerListeners();
// Instantiate all remaining (non-lazy-init) singletons.
finishBeanFactoryInitialization(beanFactory);
// Last step: publish corresponding event.
finishRefresh();
}
catch (BeansException ex) {
if (logger.isWarnEnabled()) {
logger.warn("Exception encountered during context initialization - " +
"cancelling refresh attempt: " + ex);
}
// Destroy already created singletons to avoid dangling resources.
destroyBeans();
// Reset 'active' flag.
cancelRefresh(ex);
// Propagate exception to caller.
throw ex;
}
finally {
// Reset common introspection caches in Spring's core, since we
// might not ever need metadata for singleton beans anymore...
resetCommonCaches();
contextRefresh.end();
}
}
}总结
想要掌握Spring源码应该先掌握Spring的生命周期(Bean信息是怎么加载、解析、实例化、初始化、使用、销毁的),脑海中有一个框架轮廓,知道Spring先做了什么,后做了什么,有一个大概了解。
脑海中有了Spring的轮廓之后,开始思考细节,例如:Bean信息是怎么加载的?加载的Bean信息是直接生成可用的Bean吗?每一步流程都动脑思考扩展点,怎么应用到业务中,这个扩展适合哪些业务场景等。
在看源码的过程中,要学会关联思考,源码中往往是初始化数据后,n个方法后会用到的。
最后一点,学过源码后一定要思考、做笔记,回头来看学过的知识点能在脑海中立马回忆起来,争取做到对源码为所欲为的境界!!!