在网上已经有跟多Bean的生命周期的博客,但是很多都是基于比较老的版本了,最近把整个流程化成了一个流程图。待会儿使用流程图,说明以及代码的形式来说明整个声明周期的流程。 注意因为代码比较多,这里的流程图只画出了大概的流程,具体的可以深入代码。
一、获取Bean
1、 先处理Bean 的名称,因为如果以“&”开头的Bean名称表示获取的是对应的FactoryBean对象;
2、 从缓存中获取单例Bean,有则进一步判断这个Bean是不是在创建中,如果是的就等待创建完毕,否则直接返回这个Bean对象
3、 如果不存在单例Bean缓存,则先进行循环依赖的解析
4、 解析完毕之后先获取父类BeanFactory,获取到了则调用父类的getBean方法,不存在则先合并然后创建Bean
二、创建Bean 2.1 创建Bean之前
1、 这里会先获取 RootBeanDefinition对象中的Class对象并确保已经关联了要创建的Bean的Class 。 2、 这里会检查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方法,这里用代码说明
2.1 真正的创建Bean,doCreateBean
1、 先检查 instanceWrapper变量是不是null,这里一般是null,除非当前正在创建的Bean在 factoryBeanInstanceCache中存在这个是保存还没创建完成的FactoryBean的集合。
2、 调用createBeanInstance方法实例化Bean,这个方法在后面会讲解
3、 如果当前 RootBeanDefinition对象还没有调用过实现了的 MergedBeanDefinitionPostProcessor接口的方法,则会进行调用 。
4 、 当满足以下三点(1)是单例Bean(2)尝试解析bean之间的循环引用(3)bean目前正在创建中则会进一步检查是否实现了 SmartInstantiationAwareBeanPostProcessor接口如果实现了则调用是实现的 getEarlyBeanReference方法
5 、 调用 populateBean方法进行属性填充,这里后面会讲解
6 、 调用 initializeBean方法对Bean进行初始化,这里后面会讲解
2.1.1 实例化Bean,createBeanInstance
2、 如果用户定义了Bean实例化的函数,则调用并返回
3、 如果当前Bean实现了 FactoryBean接口则调用对应的 FactoryBean接口的 getObject方法
4、 根据getBean时候是否传入构造参数进行处理
4.1 如果没有传入构造参数,则检查是否存在已经缓存的无参构造器,有则使用构造器直接创建,没有就会调用 instantiateBean方法先获取实例化的策略默认是 CglibSubclassingInstantiationStrategy,然后实例化Bean。最后返回
4.2 如果传入了构造参数,则会先检查是否实现了 SmartInstantiationAwareBeanPostProcessor接口,如果实现了会调用 determineCandidateConstructors获取返回的候选构造器。
4.3 检查4个条件是否满足一个
(1)构造器不为null,
(2)从RootBeanDefinition中获取到的关联的注入方式是构造器注入(没有构造参数就是setter注入,有则是构造器注入)
(3)含有构造参数
(4)getBean方法传入构造参数不是空
满足其中一个则会调用返回的候选构造器实例化Bean并返回,如果都不满足,则会根据构造参数选择合适的有参构造器然后实例化Bean并返回
5、 如果上面都没有合适的构造器,则直接使用无参构造器创建并返回Bean。
2.1.2 填充Bean,populateBean
2.1.3 初始化Bean,initializeBean
1、 如果Bean实现了 BeanNameAware, BeanClassLoaderAware, BeanFactoryAware则调用对应实现的方法 。
2、 Bean不为null并且bean不是合成的,如果实现了 BeanPostProcessor的 postProcessBeforeInitialization则会调用实现的 postProcessBeforeInitialization方法。在 ApplicationContextAwareProcessor类中实现了 postProcessBeforeInitialization方法。而这个类会在Spring刷新容器准备 beanFactory的时候会加进去,这里就会被调用,而调用里面会检查Bean是不是 EnvironmentAware, EmbeddedValueResolverAware, ResourceLoaderAware, ApplicationEventPublisherAware, MessageSourceAware, ApplicationContextAware的实现类。这里就会调用对应的实现方法。代码如下
2、 Bean不为null并且bean不是合成的,如果实现了 BeanPostProcessor的 postProcessBeforeInitialization则会调用实现的 postProcessAfterInitialization方法。
到此创建Bean 的流程就没了,剩下的就是容器销毁的时候的了
三、destory方法跟销毁Bean Bean在创建完毕之后会检查用户是否指定了 destroyMethodName以及是否实现了 DestructionAwareBeanPostProcessor接口的 requiresDestruction方法,如果指定了会记录下来保存在 DisposableBeanAdapter对象中并保存在bean的 disposableBeans属性中。代码在 AbstractBeanFactory的 registerDisposableBeanIfNecessary中
最后来一个大的流程
原文作者:51CTO技术栈 出处:developer.51cto.com/art/202002/…