Spring循环依赖流程
2020-07-08 18:24:42 3 举报
spring循环依赖源码
作者其他创作
大纲/内容
此时object类型为RuntimeBeanReference
二级缓存
getBean(String name)
填充bean,获取bean属性
...
进入方法
13个方法
beanFactory.preInstantiateSingletons()
singletonObject = singletonFactory.getObject()
开始
B
private A a;....
singletonFactory为上一个方法的匿名内部类createBean
AutowiredFieldElement类
A
private B b;....
populateBean()
this.beanFactory
inject()
没有存二级缓存是因为allowEarlyReference为false
beanFactory.resolveDependency()
element.inject()
初始化bean
第二次递归可以从三级缓存中获取到A类Factory,把A加到二级缓存并删除三级缓存
if (value instanceof RuntimeBeanReference)
applyPropertyValues()
valueResolver.resolveValueIfNecessary()
三级缓存
resolveCandidate()
populate方法结束
Spring循环依赖源码跟踪
第四步
B类
doCreateBean方法结束createBean方法结束
for (PropertyValue pv : original)
A类
refresh()
new ArrayList<>(this.beanDefinitionNames)
finishBeanFactoryInitialization(beanFactory)
顺序执行
第三步remove
for(String beanName : beanNames)
AbstractApplicationContext
refresh()........
第一次将A类的beanFactory添加到三级缓存第二次将B类的beanFactory添加到三级缓存
postProcessProperties()
metadata.inject()
匿名内部类,在调用时加载该类
第一步
true
第三步
if(mbd.isSingleton())
1.遍历beanName,用debug条件过滤到我们需要加载的A类
getSingleton(beanName)
DefaultSingletonBeanRegistry类
font color=\"#ff9933\
返回null
获取属性
1.getBean(A)2.getBean(B)3.getBean(A)
第五步
if (earlySingletonExposure) {font color=\"#ff0000\
doGetBean()
第二步
第一次将B类添加到一级缓存第二次将A类添加到一级缓存
1.第一次递归加载属性B类2.第二次递归加载属性A类
doResolveDependency()
一级缓存
for(BeanPostProcessor bp : getBeanPostProcessors())
FAQ1.为什么使用构造器注入属性时不能解决循环依赖? 在doCreateBean方法中(创建bean时)分两步实例化和初始化来操作,并将实例化好的对象提前暴露出去(加入三级缓存),供其他调用。而如果使用构造器注入属性则在实例化时必须使用构造方法,构造方法中又依赖B对象的实例化,B实例化又依赖A对象实例化,则陷入死循环,无法创建,Spring会报BeanCurrentlyInCreationException。2.一级缓存能否解决? 不能,在三个级别的缓存中,是有区别的(1.完成实例化且初始化的对象;2.完成实例化但没有初始化的对象;3.beanFactory对象)如果只有一级缓存,存放实例化完但没有初始化的对象,属性值都为空,则有问题3.二级缓存能否解决? 理论上是可以解决的,但三级缓存的作用在于
prepareRefresh()
使用@Autowired注解注入时,则在这里遍历到AutowiredAnnotationBeanPostProcessor类时,加载属性非注解形式则在applyPropertyValues()方法里加载属性
Object originalValue = pv.getValue()
0 条评论
下一页