【六】springboot启动源码 – finishBeanFactoryInitialization

finishBeanFactoryInitialization 源码解析

Instantiate all remaining (non-lazy-init) singletons.
初始化剩下非懒加载的实例对象

finishBeanFactoryInitialization方法第918行,beanFactory.preInstantiateSingletons();
在这里插入图片描述
preInstantiateSingletons方法,遍历beanDefinitionNames,通过mergedBeanDefinitions来获取每一个RootBeanDefinition,并判断他是否是factorybean,如果不是,调用getBean()方法

在这里插入图片描述
doGetBean方法
第252行,transformedBeanName(name),用于返回真实beanName,如果是beanName以&开头(表示factoryBean),去掉&并返回。通过Map<String, String> aliasMap来获取该beanName是否为别名,如果key有值,返回value
在这里插入图片描述
第256行,getSingleton(beanName),通过singletonObjects来获取之前是否已经注入到IOC中

Eagerly check singleton cache for manually registered singletons.

在这里面做了三级缓存,也是spring解决循环依赖的地方,在后面分析
这里做调试的类没有进行过初始化,singletonObjects返回null
在这里插入图片描述
AbstractBeanFactory第300行,typeCheckOnly一般都为false(用于类型检查实例是否获得,而不是实际使用)
进入markBeanAsCreated方法
判断alreadyCreated(已标记为创建)是否包含beanName,这里通过双重校验锁,如果不包含,将beanName添加到alreadyCreated
在这里插入图片描述
clearMergedBeanDefinition方法,将bd的stale设置为true,并从mergedBeanDefinitionHolders移除beanName
在这里插入图片描述
AbstractBeanFactory第309行,getMergedLocalBeanDefinition方法
在这里插入图片描述
进入getMergedLocalBeanDefinition方法
从mergedBeanDefinitions取出beanName对应的RootBeanDefinition
在这里插入图片描述
回到AbstractBeanFactory,判断类是否有@DependsOn注解
第332行,开始创建对象实例
在这里插入图片描述

getSingleton.getObject()

进入getSingleton方法
通过双重校验再次判断singletonObjects是否存在beanName
第234行,开始调用ObjectFactory(类似Supplier)的getObject方法
在这里插入图片描述
在这里插入图片描述
第514行,resolveBeanClass,解析beanClass,如果是对象被代理,返回代理对象的class
在这里插入图片描述
第531行,resolveBeforeInstantiation,如果有自定义InstantiationAwareBeanPostProcessor实现,调用postProcessBeforeInstantiation(实例化之前执行)。可以实例化自定义bean,但是这个回调会在所有bean实例化的时候都执行。非自定义的类也会在这里实例化,会有不可预估的风险,如果方法返回的不为null,表示已经实例化,直接返回这个bean作为创建的单例对象,并注册到IOC容器。

Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.

在这里插入图片描述
第542行,doCreateBean,正式开始实例化bean
在这里插入图片描述

doCreateBean

第582行,进入createBeanInstance
在这里插入图片描述

createBeanInstance

determineConstructorsFromBeanPostProcessors,在这里回调SmartInstantiationAwareBeanPostProcessor的determineCandidateConstructors方法,可以用来设置类的自定义构造器

在这里插入图片描述
instantiateBean方法,通过默认无参构造来实例化bean
在这里插入图片描述
进入instantiateBean方法,第1326行。beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, this);
通过实例化策略执行器开始实例化bean,主要还是通过构造器实例化,过程略。
返回实例对象后,封装成BeanWrapper并返回
在这里插入图片描述

applyMergedBeanDefinitionPostProcessors

实例化bean之后,第594行,applyMergedBeanDefinitionPostProcessors方法。会在这里回调MergedBeanDefinitionPostProcessor接口postProcessMergedBeanDefinition方法
在这里插入图片描述

populateBean

在这里插入图片描述
进入populateBean方法,第1399行,回调InstantiationAwareBeanPostProcessor接口的postProcessAfterInstantiation。用于自定义判断bean与beanName是否满足相同预期结果
在这里插入图片描述
第1431行,回调InstantiationAwareBeanPostProcessor接口的postProcessProperties方法
在这里插入图片描述

这里有一个spring的实现类AutowiredAnnotationBeanPostProcessor,这里会根据进行@Autowire注解的依赖注入,会实例化依赖的类
在这里插入图片描述
在这里插入图片描述
依然会通过beanFactory.getBean(beanName);来实例化依赖的类

initializeBean

在这里插入图片描述
进入initializeBean,第1791行,invokeAwareMethods

invokeAwareMethods

在这里插入图片描述
判断bean是否实现Aware,如果当前对象是cglib生成的代理对象,默认实现EnhancedConfiguration接口,该接口继承了BeanFactoryAware
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
把beanFactory设置到bean中
在这里插入图片描述
在这里插入图片描述

applyBeanPostProcessorsBeforeInitialization

在这里插入图片描述
在这里执行BeanPostProcessor接口的postProcessBeforeInitialization回调
在这里插入图片描述

InitDestroyAnnotationBeanPostProcessor回调

InitDestroyAnnotationBeanPostProcessor的postProcessBeforeInitialization,会触发bean的@PostConstruct注解方法(充当init-method)
在这里插入图片描述

ConfigurationPropertiesBindingPostProcessor回调

ConfigurationPropertiesBindingPostProcessor的postProcessBeforeInitialization,会执行@ConfigurationProperties的自定绑定model字段逻辑。
在这里插入图片描述
判断类上是否有@ConfigurationProperties,并创建ConfigurationPropertiesBean返回
在这里插入图片描述
在这里插入图片描述
获取待绑定的字段,从PropertySource中寻找该字段对应的值(PropertySource值在之前已经缓存)
在这里插入图片描述
最终通过JavaBeanBinder的setValue方法,来为字段赋值
在这里插入图片描述

invokeInitMethods

在这里插入图片描述
会回调InitializingBean接口的afterPropertiesSet
在这里插入图片描述
如果对象有初始化方法(在其他配置类中定义的@Bean(initMethod = “doInit”)),会进行调用
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

applyBeanPostProcessorsAfterInitialization

在这里插入图片描述
调用BeanPostProcessor的postProcessAfterInitialization方法

getSingleton

上面已经将对象实例化。
第633行,getSingleton方法。
在这里插入图片描述

registerDisposableBeanIfNecessary

第661行,registerDisposableBeanIfNecessary方法。
待补充

addSingleton(beanName, singletonObject)

注册单例对象到IOC容器
在这里插入图片描述

循环依赖的处理

前提:开启允许循环依赖,springboot 2.6 之后就默认关闭了。
A(cicA)与B(cicB)相互依赖,A先进行初始化

  1. A完成bean实例创建
    在这里插入图片描述

  2. 判断是否开启了循环依赖,并添加A的bean实例工厂到beanFactory的singletonFactories中(作为第三级缓存)
    在这里插入图片描述

  3. 在populateBean方法中,回调InstantiationAwareBeanPostProcessor的postProcessProperties方法。这里我们需要关注AutowiredAnnotationBeanPostProcessor类。执行依赖注入
    在这里插入图片描述
    通过A上被@Autowire修饰的成员变量,获取到待注入的类(这里的cicB是与当前类互为循环依赖的),封装成InjectedElement
    在这里插入图片描述
    遍历这两个InjectedElement,依次进行解析,并调用beanFactory.getBean(beanName)。这里的bean是cicB
    在这里插入图片描述

  4. B完成bean实例创建,和A的第1步一样

  5. 添加B的bean实例工厂到beanFactory的singletonFactories中,和A的第2步一样

  6. 依然通过AutowiredAnnotationBeanPostProcessor的postProcessProperties方法,获取B下的被@Autowire修饰的成员变量,来执行依赖注入
    在这里插入图片描述
    和A的第3步一样,调用beanFactory.getBean(beanName)。这里的bean是cicA
    来到doGetBean的getSingleton(beanName)方法,从这里尝试获取A的对象
    a. 首先从一级缓存singletonObjects获取bean,因为A对象只是实例化,还没有初始化,因此还没有注入到singletonObjects中
    在这里插入图片描述
    b.一级缓存中获取不到bean,从二级缓存earlySingletonObjects获取,此时二级缓存也没有A的对象
    在这里插入图片描述
    c. 这里通过双重校验锁再次确保一、二级缓存都不存在bean。从三级缓存singletonFactories中获取到对象的ObjectFactory,通过执行ObjectFactory.getObject方法。调用如下的函数式接口,beanName为cicA,bean为实例化之后的cicA对象,返回该对象
    在这里插入图片描述
    这里会调用SmartInstantiationAwareBeanPostProcessor的getEarlyBeanReference方法
    在这里插入图片描述
    返回cicA对象,将对象放入二级缓存earlySingletonObjects中
    在这里插入图片描述
    获取到cicA之后,通过Field将cicA设置到cicB的字段中
    在这里插入图片描述

  7. cicB完成初始化,注册到一级缓存,从二、三级缓存删除

  8. 返回cicB,通过Field将cicB设置到cicA的字段中
    在这里插入图片描述

  9. cicA完成初始化,注册到一级缓存,从二、三级缓存删除
    在这里插入图片描述

总结

在这里插入图片描述

FactoryBean


版权声明:本文为qq_36382225原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
THE END
< <上一篇
下一篇>>