循环依赖解决方案详解
2023-11-28 22:54:21 0 举报
登录查看完整内容
面试利器!
作者其他创作
大纲/内容
判断value是否属于RuntimeBeanReference
判断A对象是否正在创建中
先实例化A
doCreateBean(xxx)
返回到方法:font color=\"#e74f4c\
点进上述方法,从一级缓存查找
getSingleton(beanName);从缓存中获取查找实例:先从一级查找:此方法很重要★
getSingleton(beanName);此时此方法显得很重要:先从一级缓存中获取,没有则判断
createBean(xxx)
getBean(beanName)
执行代码:singletonFactory.getObject();
填充属性:B中的a
font color=\"#e74f4c\
初始化A:给A中属性b赋值
doGetBean(x,x)
点进入前面返回值得到一个type,执行下面代码:this.beanFactory.getBean(resolveName)
lambda表达式:()->{try{return font color=\"#000000\
判断A对象是在创建中,注意这里不一样了
删除掉三级缓存中key为a的内容
B已实例化,接着就是:初始化B
此过程步骤和初始化A一致,故省略
将代码一直返回到getBean(beanName)方法处
找见:font color=\"#e74f4c\
将A完全体对象存入到一级缓存中;移除掉三级和二级缓存中key为a的内容
判断B对象是否正在创建中
B已完成实例化和初始化,则再次回到初始化A的步骤,将完成体B赋值给A中的b属性
进入相关代码,从二级缓存中获取A对象
结束循环,至此循环依赖解决
得到返回值A@123
通过前面方法得到B对象且赋值给A对象的属性b中
往三级缓存中font color=\"#7bd144\
经过上述流程一级缓存中有B对象
第一步:将两个参数添加到一级缓存中;第二步:将三级缓存中的beanName为b的内容移除;第三步:移除二级缓存中beanName为b的内容
否
此方法找见BeanUtils.instantiateClass(xxx),点进找见ctor.newInstance(xxx);代码完成反射创建对象
此方法就是往三级缓存中添加数据,参数见初始化A
是
B对象中a属性得到且赋值,初始化B完成
在执行singletonFactory.getObject()方法,实则是底层是(lambda表达式)getEarlyxxx()
doGetBean进来是:getSingleton(beanName);先从一级缓存中找,没有则判断
进入addSingleton方法内:将B完全体存入到一级缓存中
点进refersh()方法中找见:finishBeanFactoryInitialization(beanFactory)方法
for(String beanName:beanNames):
找见:beanFactory.preInstantiateSingletons();此方法是实例化bean的开始
进入populateBean方法找:font color=\"#4669ea\
spring在创建bean之前会先从容器中查找,如果找不到则再创建
doGetBean(有参数不重点懒得写)
接着上述代码继续往下跟
getSingleton(beanName);从缓存中获取查找实例:先从一级查找:★
接着上述代码继续往下跟,基本流程和初始化A一样
二级缓存中没有从三级缓存中获取(根据键获取值),得到Object<?> singletonFactory
半成品:只是申请了空间,生成对象地址值,还没有进行初始化,属性赋值
加载spring配置文件:ClassPathXmlApplicationContext
进入到ClassPathXmlApplicationContext内部找到其构造方法中的refresh()方法
点进方法 ,判断一级缓存中是否包含,(刚开始必然没有)
//A对象中属性值bString propertyName=pv.getName//originalValue:RuntimeBeanReference运行时Bean引用Object originalValue=pv.getValue
刚开始实例化B对象必然不是在创建中,期间代码执行和实例化A此步骤是一样的,接下来就是实例化B对象
创建出B对象半成品B@123
点进getObject()方法底层是font color=\"#ec7270\
容器中没有找到那么创建对象实例:font color=\"#e74f4c\
返回空对象:singletonObject,即容器中没有找到
for(String beanName:beanNames):循环开启
空
执行getBean(beanName);方法,开始从容器中查找
得到实例A对象(半成品)
相关代码执行完毕后(先从一级缓存中获取没有则三级添加),三级缓存现在存储数据为:ab的键值对,值都是lambda表达式(getEarxxx)
直接返回getBean(beanName)
上述代码是在容器中找A对象的B属性的实例化,所以走:getBean(beanName),方法找B实例化对象
收藏
0 条评论
回复 删除
下一页