Spring源码学习三——Bean的生命周期主流程

一、实例化

前文讲到容器启动方法refresh()里面,调用finishBeanFactoryInitialization()方法会实例化所有非懒加载的单例bean,bean的生命周期得入口就在这里在这里插入图片描述
前面那些都不重要,进入红框中的方法
在这里插入图片描述
beanNames里面是BeanDefinition的名称,singletonObjects是单例池。比较一下还有一些我们自己创建的类未被实例化
在这里插入图片描述
如果一个bean不是抽象的、是单例的且不是懒加载就会进入if,然后如果这个bean是FactoryBean,会特殊处理,但最终都会进入getBean(),这里没有直接创建bean,而是先从缓存里面拿,如果没有就创建bean,进入getBean

1.1 getBean

进入doGetBean();spring里面带do的方法就是真正做事的。
在这里插入图片描述
getSingleton(beanName);第一次得到的肯定是空,往下跳过不重要的部分
在这里插入图片描述
进入getSingleton
在这里插入图片描述
这行调用了函数式接口的getObject()
在这里插入图片描述
继续进入,就回到了lambda表达式里面的createBean(),开始创建bean的实例

1.2 createBean

进入createBean之后一路往下到达doCreateBean,真正做事的方法
在这里插入图片描述
先进入createBeanInstance,往下走到instantiateBean
在这里插入图片描述
注释是说没有特殊处理:简单的使用无参构造方法
在这里插入图片描述
进入beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, this);
在这里插入图片描述
拿到无参构造器方法保存到BeanDefinition的resolvedConstructorOrFactoryMethod属性
在这里插入图片描述
最终调用newInstance得到了实例对象,其实就是用了反射机制生成对象

二、初始化

在这里插入图片描述
看注释,这里就是初始化开始的地方

2.1 populateBean

populateBean()方法就是属性注入,如果有依赖其他bean就会先完成其他bean的生命周期。这就可能会引发循环依赖,循环依赖的问题我在其他文章中有讲,这里就不详细说了,现在只关心主流程。

2.2 Aware回调

exposedObject = initializeBean(beanName, exposedObject, mbd);–>invokeAwareMethods(beanName, bean);
在这里插入图片描述
Aware的顺序是BeanNameAware–>BeanClassLoaderAware–>BeanFactoryAware

2.3 前置增强postProcessBeforeInitialization

返回到initializeBean方法从wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);进入
在这里插入图片描述
这里执行了所有注册过的BeanPostProcessor的postProcessBeforeInitialization方法,用来处理指定的bean。

2.3.1 @PostConstruct

这里特别注意一下有个CommonAnnotationBeanPostProcessor的增强器,它的构造方法
在这里插入图片描述
会设置初始化注解PostConstruct,它的postProcessBeforeInitialization继承至InitDestroyAnnotationBeanPostProcessor
在这里插入图片描述
postProcessBeforeInitialization执行进入

findLifecycleMetadata(bean.getClass());–>buildLifecycleMetadata()
在这里插入图片描述

这里将@PostConstruct注解的方法加入到了currInitMethods是一个List,最终加入了LifecycleMetadata的initMethods
所以注解@PostConstruct多个方法都会被执行,继续看在哪里执行,回到postProcessBeforeInitialization,从metadata.invokeInitMethods(bean, beanName);进入
在这里插入图片描述
这里执行所有的初始化方法

2.4 执行初始化方法

2.4.1 afterPropertiesSet

返回到initializeBean方法从invokeInitMethods(beanName, wrappedBean, mbd);进入
在这里插入图片描述
先检查是否实现InitializingBean,如果有就执行afterPropertiesSet方法,继续往下
在这里插入图片描述
getInitMethodName()拿到的是手动指定的初始化方法,即xml文件配置bean时指定的init-method属性。之后执行init-method指定的方法

2.4.2 init-method

mbd.getInitMethodName()获取的是initMethodName,看看它在何时赋值
在这里插入图片描述
最终发现是在xml解析的时候赋值的
在这里插入图片描述
在这里插入图片描述
initMethodName类型是String,也就是说只能有一个init-method方法

2.5 后置增强postProcessAfterInitialization

返回到initializeBean方法从wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
进入
在这里插入图片描述
执行所有的后置增强

三、销毁

3.1 destroy

在Spring容器关闭的时候,会去销毁所有的单例Bean
在这里插入图片描述
进入

close()–doClose();–>destroyBeans();–>super.destroySingletons();–> destroySingleton(disposableBeanNames[i]);–>super.destroySingleton(beanName);–>destroyBean(beanName, disposableBean);–>bean.destroy();
在这里插入图片描述

3.1.1 @PreDestroy

bean在销毁的时候会执行DestructionAwareBeanPostProcessor的postProcessBeforeDestruction方法
在这里插入图片描述
InitDestroyAnnotationBeanPostProcessor实现了DestructionAwareBeanPostProcessor,因此会执行它的postProcessBeforeDestruction,进而执行metadata.invokeDestroyMethods(bean, beanName);
前面讲过@PostConstruct,在那里同时处理的还有@PreDestroy注解。最终将@PreDestroy注解的方法名添加到了LifecycleMetadata.destroyMethods,而这些方法都将在这里一并执行

3.1.2 DisposableBean

在这里插入图片描述

如上图,如果bean实现了DisposableBean接口,会先执行它自己实现的destroy方法

3.1.3 destroy-method

最后会执行xml指定的destroy-method方法,与init-mehod类似。
在这里插入图片描述
这里的destroyMethodName就是来自xml指定的destroy-method

四、总结

在这里插入图片描述

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
Spring框架提供了对Bean生命周期管理。在Spring码中,Bean生命周期由两个关键接口定义:BeanFactory和BeanPostProcessor。 BeanFactory是Spring的核心接口之一,它负责管理所有的Bean,并负责实例化、配置和管理它们的整个生命周期BeanFactory接口定义了许多方法,如getBean()和registerBeanDefinition(),用于获取和注册BeanBeanPostProcessor是另一个重要的接口,它定义了在Bean初始化的不同阶段可以插入自定义逻辑的扩展点。通过实现BeanPostProcessor接口,开发人员可以在Bean的实例化、初始化和销毁等阶段插入自己的逻辑。BeanPostProcessor接口中定义了两个方法:postProcessBeforeInitialization()和postProcessAfterInitialization()。 在Spring码中,Bean生命周期主要涉及以下几个重要的类和方法: 1. DefaultListableBeanFactory类:此类实现了BeanFactory接口,是Spring容器的核心实现类之一。它负责读取Bean的定义信息,并根据这些定义信息创建和管理Bean。 2. AbstractAutowireCapableBeanFactory类:此类是DefaultListableBeanFactory的子类,它提供了Bean的自动装配功能。它包含了Bean的实例化、属性注入、初始化和销毁等关键步骤。 3. AnnotationConfigApplicationContext类:此类是通过注解配置来创建Spring容器的一种方式。它根据指定的配置类,扫描注解并完成Bean的初始化和管理。 4. BeanDefinition类:此类定义了Bean的配置信息,包括Bean的类名、属性值和依赖关系等。在Bean生命周期中,BeanDefinition起到了重要的作用。 以上只是Spring Bean生命周期码的一部分,如果你对Spring Bean生命周期码感兴趣,建议你阅读Spring码以获得更详细的了解。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值