【六】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先进行初始化
-
A完成bean实例创建
-
判断是否开启了循环依赖,并添加A的bean实例工厂到beanFactory的singletonFactories中(作为第三级缓存)
-
在populateBean方法中,回调InstantiationAwareBeanPostProcessor的postProcessProperties方法。这里我们需要关注AutowiredAnnotationBeanPostProcessor类。执行依赖注入
通过A上被@Autowire修饰的成员变量,获取到待注入的类(这里的cicB是与当前类互为循环依赖的),封装成InjectedElement
遍历这两个InjectedElement,依次进行解析,并调用beanFactory.getBean(beanName)。这里的bean是cicB
-
B完成bean实例创建,和A的第1步一样
-
添加B的bean实例工厂到beanFactory的singletonFactories中,和A的第2步一样
-
依然通过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的字段中
-
cicB完成初始化,注册到一级缓存,从二、三级缓存删除
-
返回cicB,通过Field将cicB设置到cicA的字段中
-
cicA完成初始化,注册到一级缓存,从二、三级缓存删除