Spring如何处理循环引用
2021-11-18 15:34:06 12 举报
spring循环依赖
作者其他创作
大纲/内容
24
doCreateBean()
初始化操作
28
29.返回beanB
这一步骤之前,都是在解析B 的属性,到这里解析出来是引用类型的A对象,于是继续调用BeanFactory去容器中获取A对象
将完整的B放入一级缓存中
14
10
这里会将当前bean A 表示为正在创建中
3
getBean(beanB)
25. 从三级缓存中根据ObjectFactory 创建 beanA 对象返回
放入三级缓存,注意放的不是beanB对象,而是ObjectFactory对象
3. 构造注入为什么不能解决循环依赖
initializeBean()
doGetBean(beanB)
beanB 是否创建中? false
getSingleton(beanB)
8
doGetBean(String nameA)
<bean id=\"a\" class=\"com.qiuguan.spring.bean.A\"> <property name=\"b\" ref=\"b\"/> </bean> <bean id=\"b\" class=\"com.qiuguan.spring.bean.B\"> <property name=\"a\" ref=\"a\"/> </bean>
添加到一级缓存中,这个方法是在上面的第四步方法的内部
beanFactory.getBean(resolvedNameA)resolvedName 是 A 的beanName
1
对象a是否创建中? false
这里完成实例化
AbstractAutowireCapableBeanFactory
populateBean()
singletonObjects一级缓存
applyPropertyValues()
beanB 是否创建中? true
13
这一步骤之前,都是在解析A 的属性,到这里解析出来是引用类型的B对象,于是继续调用BeanFactory去容器中获取b对象
答:在没有AOP的情况下,是可以解决的;但如果存在AOP就不行了,因为ObjectFactory 调用 getObject()方法时每次返回的代理对象都是不同的,这样在单例bean中就有问题了,所以需要二级缓存来保存代理对象,这样保证每次获取的都是同一个代理对象参考文档:https://www.cnblogs.com/semi-sub/p/13548479.html
getSingleton(beanA)
对象a是否创建中? true
AbstractBeanFactory
getSingleton(beanNameA)
9
valueResolver.resolveValueIfNecessary()
准备说明
属性赋值
getBean(String nameA)
7.填充B对象
beanFactory.getBean(resolvedNameB)resolvedName 是 B 的beanName
17
DefaultListableBeanFactory
createBeanInstance()
27
doGetBean(beanA)
4
创建B的实例
19
18
23
接下来就是重复A的过程
2.只使用 二级缓存能不能解决循环依赖问题?
26.将从三级缓存中获取的A对象赋值给B对象
6
16
如果上面可以返回,后面就不执行
12
11
循环依赖经典面试题
创建A对象
26
getBean(beanA)
22
ClassPathXmlApplicationContext
31.将beanB赋值给A对象的属性,然后初始化A
2
DefaultSingletonBeanRegistry
//beanNames = {\"a\
singletonFactories三级缓存
21
addSingleton()
5
创建阶段
32.将beanA加入到一级缓存中
resolveReference()
earlySingletonObjects二级缓存
30.返回beanB 给 A 对象
15.填充A对象
答:解决循环依赖的本质是将实例化和初始化过程分隔开来,先通过构造函数构建一个不完整的Bean
20
1.只使用一级缓存能不能解决循环依赖问题?
0 条评论
下一页