Spring单例Bean的创建流程
2021-07-17 15:36:02 4 举报
spring单例Bean的创建流程;源码调用时序;spring循环依赖解决
作者其他创作
大纲/内容
doResolveDependency
为什么要使用3级缓存而不是2级缓存呢?循环依赖实例:ClassA -> ClassB -> ClassC -> ClassA正常情况下2级缓存确实就能解决循环依赖的问题,但是在当ClassA有Aop切面的时候,ClassA会被代理,由于第3级缓存是一个匿名内部类,是通过调用ObjectFactory#getObject即AbstractAutowireCapableBeanFactory#getEarlyBeanReference方法获取到的对象,因此在ClassA被代理的情况下,每次调用该方法都会返回不同的代理对象,又由于要创建的是单例Bean,所以需要在第一次调用的时候将返回的对象存入2级缓存,下次调用直接从2级缓存获取,这样就保证了Bean是单例的。
注解在Field上则使用AutowiredFieldElement
由于要先调用构造方法创建Bean的对象之后才会存入第3级缓存,所以如果是通过构造方法注入依赖Bean的情况,Spring是无法解决循环依赖的,会抛出BeanCurrentlyInCreationException异常。还有如果是prototype类型的Bean没有将对象保存进3级缓存,每次都是重新创建,所以也无法解决循环依赖的问题。
调用bean实现的Aware接口的方法,BeanPostProcessor接口的postProcessBeforeInitialization方法,以及如果实现了InitializingBean接口的afterPropertiesSet方法,最后调用BeanPostProcessor接口的postProcessAfterInitialization
AutowiredAnnotationBeanPostProcessor#postProcessProperties
AutowiredAnnotationBeanPostProcessor#AutowiredMethodElement#inject
AbstractAutowireCapableBeanFactory#createBean
DefaultListableBeanFactory#preInstantiateSingletons
InjectionMetadata#inject
allowEarlyReference参数为true,首次查询时第3级缓存还没有数据,在调用addSingletonFactory后会将beanFactory对象存入缓存,再次调用时取到3级缓存并调用ObjectFactory#getObject方法获取对象,将返回的bean对象存入2级缓存,然后删掉3级缓存的内容
属性@Autowired注入,根据注解是在Field还是在Method上来决定使用哪个处理类
finishBeanFactoryInitialization
DefaultListableBeanFactory#resolveDependency
createBeanInstance
applyBeanPostProcessorsBeforeInstantiation和applyBeanPostProcessorsAfterInitialization,Bean初始化前后后置处理程序。实现了BeanPostProcessor的类
resolveBeforeInstantiation
第3级缓存存入ObjectFactory接口实现,也就是getEarlyBeanReference方法回调,传入了bean对象的引用,此时的Bean对象还没有初始化属性,可以解决通过属性注入的循环依赖
返回实例化完成的Bean对象
实例化单例Bean
AbstractApplicationContext#refresh()
返回Bean对象
InstantiationAwareBeanPostProcessor接口实现类,注入的BeanPostProcessor
3级缓存中存在Bean对象就直接返回
通过构造方法实例化Bean对象
initializeBean
3级缓存对象分别为:singletonObjects 最终对象earlySingletonObjects 早期暴露对象singletonFactories ObjectFactory对象
取2级缓存中Bean对象,如果存在则返回该Bean对象
AbstractBeanFactory#doGetBean
非单例Bean创建流程跟此流程相差不大,区别在于非单例Bean每次都是重新创建,不会把创建后的Bean对象存入缓存
AbstractAutowireCapableBeanFactory#doCreateBean
回调参数ObjectFactory接口实现类的getObject方法,该方法调用前后会检查是否可以可以创建bean。before检查中构造方法的循环依赖会抛出BeanCurrentlyInCreationException异常
将Bean对象放入第1级缓存,并删除2、3级缓存中对应的对象
singletonFactory.getObject()
AbstractBeanFactory#getBean(String name)
addSingletonFactory
单例bean
填充Bean,递归初始化属性Bean
populateBean
DependencyDescriptor#resolveCandidate
先查缓存3级缓存解决循环依赖
addSingleton
收藏
0 条评论
下一页