文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

怎样理解Spring Bean生命周期

2023-06-16 15:45

关注

怎样理解Spring Bean生命周期,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。

在网上已经有跟多Bean的生命周期的博客,但是很多都是基于比较老的版本了,最近把整个流程化成了一个流程图。待会儿使用流程图,说明以及代码的形式来说明整个声明周期的流程。注意因为代码比较多,这里的流程图只画出了大概的流程,具体的可以深入代码。

一、获取Bean

怎样理解Spring Bean生命周期 

第一阶段获取Bean

这里的流程图的入口在 AbstractBeanFactory类的 doGetBean方法,这里可以配合前面的 getBean方法分析文章进行阅读。主要流程就是

先处理Bean 的名称,因为如果以“&”开头的Bean名称表示获取的是对应的FactoryBean对象;

从缓存中获取单例Bean,有则进一步判断这个Bean是不是在创建中,如果是的就等待创建完毕,否则直接返回这个Bean对象

如果不存在单例Bean缓存,则先进行循环依赖的解析

解析完毕之后先获取父类BeanFactory,获取到了则调用父类的getBean方法,不存在则先合并然后创建Bean

二、创建Bean

2.1 创建Bean之前

怎样理解Spring Bean生命周期

在真正创建Bean之前逻辑

这个流程图对应的代码在 AbstractAutowireCapableBeanFactory类的 createBean方法中。

这里会先获取 RootBeanDefinition对象中的Class对象并确保已经关联了要创建的Bean的Class 。

这里会检查3个条件

(1)Bean的属性中的 beforeInstantiationResolved字段是否为true,默认是false。

(2)Bean是原生的Bean

(3)Bean的 hasInstantiationAwareBeanPostProcessors属性为true,这个属性在Spring准备刷新容器钱转杯BeanPostProcessors的时候会设置,如果当前Bean实现了 InstantiationAwareBeanPostProcessor则这个就会是true。

当三个条件都存在的时候,就会调用实现的 InstantiationAwareBeanPostProcessor接口的 postProcessBeforeInstantiation方法,然后获取返回的Bean,如果返回的Bean不是null还会调用实现的 BeanPostProcessor接口的 postProcessAfterInitialization方法,这里用代码说明:

怎样理解Spring Bean生命周期 3、如果上面3个条件其中一个不满足就不会调用实现的方法。默认这里都不会调用的这些 BeanPostProcessors的实现方法。然后继续执行后面的 doCreateBean方法。

2.1 真正的创建Bean,doCreateBean

怎样理解Spring Bean生命周期

doCreateBean方法逻辑

这个代码的实现还是在 AbstractAutowireCapableBeanFactory方法中。流程是

先检查 instanceWrapper变量是不是null,这里一般是null,除非当前正在创建的Bean在 factoryBeanInstanceCache中存在这个是保存还没创建完成的FactoryBean的集合。

调用createBeanInstance方法实例化Bean,这个方法在后面会讲解

如果当前 RootBeanDefinition对象还没有调用过实现了的 MergedBeanDefinitionPostProcessor接口的方法,则会进行调用 。

当满足以下三点(1)是单例Bean(2)尝试解析bean之间的循环引用(3)bean目前正在创建中则会进一步检查是否实现了 SmartInstantiationAwareBeanPostProcessor接口如果实现了则调用是实现的 getEarlyBeanReference方法

调用 populateBean方法进行属性填充,这里后面会讲解

调用 initializeBean方法对Bean进行初始化,这里后面会讲解

2.1.1 实例化Bean,createBeanInstance

怎样理解Spring Bean生命周期

实例化Bean

这里的逻辑稍微有一点复杂,这个流程图已经是简化过后的了。简要根据代码说明一下流程:

怎样理解Spring Bean生命周期

怎样理解Spring Bean生命周期

怎样理解Spring Bean生命周期

先检查Class是否已经关联了,并且对应的修饰符是否是public的

如果用户定义了Bean实例化的函数,则调用并返回

如果当前Bean实现了 FactoryBean接口则调用对应的 FactoryBean接口的 getObject方法

根据getBean时候是否传入构造参数进行处理

1 如果没有传入构造参数,则检查是否存在已经缓存的无参构造器,有则使用构造器直接创建,没有就会调用 instantiateBean方法先获取实例化的策略默认是 CglibSubclassingInstantiationStrategy,然后实例化Bean。最后返回

2 如果传入了构造参数,则会先检查是否实现了 SmartInstantiationAwareBeanPostProcessor接口,如果实现了会调用 determineCandidateConstructors获取返回的候选构造器。

3 检查4个条件是否满足一个

(1)构造器不为null,

(2)从RootBeanDefinition中获取到的关联的注入方式是构造器注入(没有构造参数就是setter注入,有则是构造器注入)

(3)含有构造参数

(4)getBean方法传入构造参数不是空

满足其中一个则会调用返回的候选构造器实例化Bean并返回,如果都不满足,则会根据构造参数选择合适的有参构造器然后实例化Bean并返回

如果上面都没有合适的构造器,则直接使用无参构造器创建并返回Bean。

2.1.2 填充Bean,populateBean

怎样理解Spring Bean生命周期

填充Bean

这里还是根据代码来说一下流程

怎样理解Spring Bean生命周期

怎样理解Spring Bean生命周期怎样理解Spring Bean生命周期

怎样理解Spring Bean生命周期

检查当前Bean是否实现了 InstantiationAwareBeanPostProcessor的 postProcessAfterInstantiation方法则调用,并结束Bean的填充。2、将按照类型跟按照名称注入的Bean分开,如果注入的Bean还没有实例化的这里会实例化,然后放到 PropertyValues对象中。3、如果实现了 InstantiationAwareBeanPostProcessor类的 postProcessProperties则调用这个方法并获取返回值,如果返回值是null,则有可能是实现了过期的 postProcessPropertyValues方法,这里需要进一步调用 postProcessPropertyValues方法4、进行参数填充

2.1.3 初始化Bean,initializeBean

怎样理解Spring Bean生命周期

初始化Bean

同时这里根据代码跟流程图来说明

如果Bean实现了 BeanNameAware, BeanClassLoaderAware, BeanFactoryAware则调用对应实现的方法 。

Bean不为null并且bean不是合成的,如果实现了 BeanPostProcessor的 postProcessBeforeInitialization则会调用实现的 postProcessBeforeInitialization方法。在 ApplicationContextAwareProcessor类中实现了 postProcessBeforeInitialization方法。而这个类会在Spring刷新容器准备 beanFactory的时候会加进去,这里就会被调用,而调用里面会检查Bean是不是 EnvironmentAware, EmbeddedValueResolverAware, ResourceLoaderAware, ApplicationEventPublisherAware, MessageSourceAware, ApplicationContextAware的实现类。这里就会调用对应的实现方法。代码如下

怎样理解Spring Bean生命周期

怎样理解Spring Bean生命周期

实例化Bean然后,检查是否实现了 InitializingBean的 afterPropertiesSet方法,如果实现了就会调用

Bean不为null并且bean不是合成的,如果实现了 BeanPostProcessor的 postProcessBeforeInitialization则会调用实现的 postProcessAfterInitialization方法。

到此创建Bean 的流程就没了,剩下的就是容器销毁的时候的了

三、destory方法跟销毁Bean

Bean在创建完毕之后会检查用户是否指定了 destroyMethodName以及是否实现了 DestructionAwareBeanPostProcessor接口的 requiresDestruction方法,如果指定了会记录下来保存在 DisposableBeanAdapter对象中并保存在bean的 disposableBeans属性中。代码在 AbstractBeanFactory的 registerDisposableBeanIfNecessary中

怎样理解Spring Bean生命周期

怎样理解Spring Bean生命周期

在销毁Bean的时候最后都会调用 AbstractAutowireCapableBeanFactory的 destroyBean方法。

怎样理解Spring Bean生命周期

这里是创建一个 DisposableBeanAdapter对象,这个对象实现了Runnable接口,在实现的 run方法中会调用实现的 DisposableBean接口的 destroy方法。并且在创建 DisposableBeanAdapter对象的时候会根据传入的bean是否实现了 DisposableBean接口来设置 invokeDisposableBean变量,这个变量表实有没有实现 DisposableBean接口

怎样理解Spring Bean生命周期

怎样理解Spring Bean生命周期

怎样理解Spring Bean生命周期

四、总结

最后来一个大的流程

怎样理解Spring Bean生命周期

实例化前的准备阶段

怎样理解Spring Bean生命周期

实例化前

怎样理解Spring Bean生命周期

实例化后

怎样理解Spring Bean生命周期

初始化前

怎样理解Spring Bean生命周期

关于怎样理解Spring Bean生命周期问题的解答就分享到这里了,希望以上内容可以对大家有一定的帮助,如果你还有很多疑惑没有解开,可以关注编程网行业资讯频道了解更多相关知识。

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     801人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     348人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     311人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     432人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     220人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯