深入解析Spring Bean的生命周期管理
# 写在文章开头
使用传统的java应用中创建bean的过程非常简单,直接new完创建对象即可使用,一旦bean不再使用,java自动进行垃圾回收。
相比之下spring框架中bean的生命周期相比之下却要复杂的多,正确的理解Spring bean的生命周期可以让开发更好的利用各个扩展点完成bean的各种个性化加载和初始化创建逻辑改造:

Hi,我是 sharkChili ,是个不断在硬核技术上作死的技术人,是 CSDN的博客专家 ,也是开源项目 Java Guide 的维护者之一,熟悉 Java 也会一点 Go ,偶尔也会在 C源码 边缘徘徊。写过很多有意思的技术博客,也还在研究并输出技术的路上,希望我的文章对你有帮助,非常欢迎你关注我的公众号: 写代码的SharkChili 。
同时也非常欢迎你star我的开源项目mini-redis:https://github.com/shark-ctrl/mini-redis (opens new window)
因为近期收到很多读者的私信,所以也专门创建了一个交流群,感兴趣的读者可以通过上方的公众号获取笔者的联系方式完成好友添加,点击备注 “加群” 即可和笔者和笔者的朋友们进行深入交流。
# 详解Spring声明周期
# 从注释入手
对于源码的阅读,大部分答案其实都可以在注释中得到答案,所以对于Spring生命周期,我们完全可以从顶层设计的BeanFactory得到答案:

不难看出在Spring的生命周期中,对应Bean的初始化的核心步骤和顺序为:
- 实例化
bean:这是加载一个bean的首要步骤,将需要创建的bean进行实例化。 - 属性填充:我们日常使用bean基本上都是采用
@Autowired的方式将其他bean注入,属性填充时就会将需要被注入的bean填充到当前bean实例。 - 进行各种
aware获取容器的特定能力:初始化这一步会执行到上述步骤中的各种Aware进行各种设置操作,例如BeanNameAware设置beanName、BeanFactoryAware设置BeanFactory、ApplicationContextAware将ApplicationContext传入到当前bean中。 - 初始化bean:调用
BeanPostProcessor和InitializingBean进行各种初始化工作。 - 正常使用bean。
- 销毁
bean:应用上下文被销毁,如果实现了DisposableBean或者自定义销毁方法就会将调用这些方法执行回收逻辑。
对此,笔者将其转为一张比较直观的图片让读者对整个流程有一个整体的认识,具体细节笔者会在后续文章中展开:

# 代码验证
基于上述生命周期我们给出下面这样一段示例代码,注意这里的AService和BService都是空对象:
@Service("aService")
@Slf4j
public class AService implements BeanNameAware, ApplicationContextAware, InitializingBean, DisposableBean {
@Autowired
private BService bService;
@Override
public void setBeanName(String name) {
log.info(" ******************** setBeanName");
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
log.info("******************** AService setApplicationContext");
}
@Override
public void afterPropertiesSet() throws Exception {
log.info("******************** afterPropertiesSet");
}
@Override
public void destroy() throws Exception {
log.info("******************** destroy");
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
因为PostProcessor无法执行自己的所以笔者额外继承并写了一个PostProcessor:
@Component
@Slf4j
public class MyPostProcessor implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
if ("aService".equals(beanName)) {
log.info("-*************** postProcessBeforeInitialization");
}
return null;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if ("aService".equals(beanName)) {
log.info("*************** postProcessAfterInitialization");
}
return null;
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
从输出结果可以看到bean进行初始化阶段的输出,这一点读者可以结合上图比对了解:
2024-02-19 13:09:52.994 INFO 10184 --- [ main] com.sharkChili.service.AService : ******************** setBeanName
2024-02-19 13:09:52.994 INFO 10184 --- [ main] com.sharkChili.service.AService : ******************** AService setApplicationContext
2024-02-19 13:09:52.994 INFO 10184 --- [ main] c.sharkChili.processor.MyPostProcessor : -*************** postProcessBeforeInitialization
2024-02-19 13:09:52.994 INFO 10184 --- [ main] com.sharkChili.service.AService : ******************** afterPropertiesSet
2024-02-19 13:09:52.994 INFO 10184 --- [ main] c.sharkChili.processor.MyPostProcessor : *************** postProcessAfterInitialization
2
3
4
5
# 详解源码执行流程
我们从框架的顶层设计纵览设计,可以看到Beanfacotry核心实现AbstractAutowireCapableBeanFactory,它继承了各种包含bean注册以及bean工厂管理的行为,使得自身具备一个容器的基本骨架:

# 实例化bean
我们基于上述的案例代码进行源码走读,首先进行bean实例化时执行AbstractAutowireCapableBeanFactory的createBean方法,其内部会调用createBeanInstance
@Override
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
//......
try {
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
if (logger.isTraceEnabled()) {
logger.trace("Finished creating instance of bean '" + beanName + "'");
}
return beanInstance;
}
}
//调用createBeanInstance完成bean实例化
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
//......
if (instanceWrapper == null) {
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
//......
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
代码内部会走到AbstractAutowireCapableBeanFactory的instantiateBean其内部会根据实例化策略完成bean的创建,以笔者当前这个单例bean为例,它会走SimpleInstantiationStrategy即通过反射完成bean创建:
protected BeanWrapper instantiateBean(String beanName, RootBeanDefinition mbd) {
try {
Object beanInstance;
if (System.getSecurityManager() != null) {
//......
}
else {
//通过实例化策略进行bean初始化
beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, this);
}
//......
return bw;
}
catch (Throwable ex) {
//......
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 属性填充
AbstractAutowireCapableBeanFactory的doCreateBean完成bean实例化之后的就会调用populateBean进行属性填充:
// Initialize the bean instance.
Object exposedObject = bean;
try {
populateBean(beanName, mbd, instanceWrapper);
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
2
3
4
5
6
以我们的bean为例,可以看到AutowiredAnnotationBeanPostProcessor循环获取各种处理器最终会找到AutowiredAnnotationBeanPostProcessor对需要进行注入的bean进行加载并注入:
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
//......
//AutowiredAnnotationBeanPostProcessor会拿到注入的bean的全路径
for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
PropertyValues pvsToUse = bp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
//......
}
}
//......
}
2
3
4
5
6
7
8
9
10
11
12
对应的AutowiredAnnotationBeanPostProcessor的postProcessProperties逻辑如下,可以看到其本质就是通过扫描带有Autowired注解的bean的字段封装到metadata 中调用metadata.inject完成注入:
@Override
public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {
//获取带有Autowired注解的字段
InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass(), pvs);
try {
//调用inject完成注入
metadata.inject(bean, beanName, pvs);
}
//......
return pvs;
}
2
3
4
5
6
7
8
9
10
11
12
# 初始化bean
完成属性填充后,AbstractAutowireCapableBeanFactory的doCreateBean方法会继续调用initializeBean完成后续的初始化工作:
exposedObject = initializeBean(beanName, exposedObject, mbd);
对应的核心逻辑就在下方,可以看到该方法会调用invokeAwareMethods和applyBeanPostProcessorsAfterInitialization进行初始化工作:
protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
if (System.getSecurityManager() != null) {
//......
}
else {
invokeAwareMethods(beanName, bean);
}
//......
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
查看invokeAwareMethods可以看到这个方法会拿到各种Aware进行setBeanName、setBeanClassLoader等初始化工作:
private void invokeAwareMethods(String beanName, Object bean) {
if (bean instanceof Aware) {
if (bean instanceof BeanNameAware) {
((BeanNameAware) bean).setBeanName(beanName);
}
if (bean instanceof BeanClassLoaderAware) {
ClassLoader bcl = getBeanClassLoader();
if (bcl != null) {
((BeanClassLoaderAware) bean).setBeanClassLoader(bcl);
}
}
if (bean instanceof BeanFactoryAware) {
((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
}
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
而applyBeanPostProcessorsAfterInitialization则会遍历各种框架自带或者我们自定义继承postProcessAfterInitialization(例如我们上文的MyPostProcessor)完成bean初始化工作:
@Override
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
throws BeansException {
Object result = existingBean;
for (BeanPostProcessor processor : getBeanPostProcessors()) {
Object current = processor.postProcessAfterInitialization(result, beanName);
if (current == null) {
return result;
}
result = current;
}
return result;
}
2
3
4
5
6
7
8
9
10
11
12
13
14
# 注册销毁钩子
最后AbstractAutowireCapableBeanFactory的doCreateBean会注册销毁钩子,等容器销毁时,这个bean就会被回收,自此整个bean完成的创建和初始化流程就介绍完毕了:
registerDisposableBeanIfNecessary(beanName, bean, mbd);
# 小结
以上便是笔者对于Spring周期的全部介绍,我们通过一张简易的时序图重新梳理一下流程:
- 顶层抽象
AbstractAutowireCapableBeanFactory通过SimpleInstantiationStrategy策略instantiateBean反射创建bean。 - 扫描
Autowired注解获取需要注入的bean调用InjectionMetadata的inject方法进行属性填充。 AbstractAutowireCapableBeanFactory的initializeBean调用各种Aware接口的实现和processor.postProcessAfterInitialization(result, beanName)的实现完成初始化- 注册销毁钩子
registerDisposableBeanIfNecessary。
自此文章结束,希望对你有帮助。

我是 sharkchili ,CSDN Java 领域博客专家,mini-redis的作者,我想写一些有意思的东西,希望对你有帮助,如果你想实时收到我写的硬核的文章也欢迎你关注我的公众号: 写代码的SharkChili 。
同时也非常欢迎你star我的开源项目mini-redis:https://github.com/shark-ctrl/mini-redis (opens new window)
因为近期收到很多读者的私信,所以也专门创建了一个交流群,感兴趣的读者可以通过上方的公众号获取笔者的联系方式完成好友添加,点击备注 “加群” 即可和笔者和笔者的朋友们进行深入交流。
# 参考
京东一面:Spring 为何需要三级缓存解决循环依赖:https://mp.weixin.qq.com/s/DoewrSzmsJtTjy66ZfLolA (opens new window)
《Spring实战(第4版)》