栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Spring循环依赖为什么需要三级缓存?

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Spring循环依赖为什么需要三级缓存?

if (earlySingletonExposure) {//默认为true
	if (logger.isTraceEnabled()) {
		logger.trace("Eagerly caching bean '" + beanName +
						"' to allow for resolving potential circular references");
	}
    //把ObjectFactory存到三级缓存中,三级缓存中的Bean会被后置处理来增强:代理等
	addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean)); 
}
.....
//给创建好的对象每个属性进行赋值,@Autowired发生在这里
populateBean(beanName, mbd, instanceWrapper); 
//初始化bean
exposedObject = initializeBean(beanName, exposedObject, mbd);
.....
说明:
  1. 上述代码是doCreateBean()里面的代码:首先默认将bean对应的ObjectFactory存入三级缓存中,然后属性赋值,初始化。
  2. 一级缓存存放成品bean的实例,二级缓存存放半成品bean,三级缓存存放ObjectFactory,可以在调用相应的方法时返回bean,其中二级缓存和三级缓存是专门来解决循环依赖的问题的。
原因:
  1. 解决循环依赖需要提前暴露半成品bean。
  2. 如果只有一级三级缓存,连半成品bean都没有,何从谈起解决循环依赖之说。
  3. 如果只有一级二级缓存,为了解决循环依赖,需要先将半成品bean存到二级缓存中暴露出来,但是又为了解决代理问题,暴露出来的bean还得是代理后的,所以需要此时(刚实例化bean后)就生成代理对象,否则:就会出现b中注入的a不是代理a的情况,但是spring设计之初是在bean初始化最后阶段代理,而不是在实例化后马上代理,所以加了三级缓存来延迟生成代理对象,这样只有在循环依赖这种情况下不得不用到bean的时候才生成代理bean并返回,没有循环依赖就不会生成代理bean,所以就保证了绝大多数情况还是会在初始化最后阶段生成代理对象。
总结:
其实笔者认为:spring用几级缓存无所谓,用几级都可以实现,只不过是spring做了一些取舍,最终用了三级,
如果把一二级缓存合成一个,#beanname表示成品bean,%beanname表示半成品bean,也是一样可以实现的,
只不过是丑陋、不太合理一点。

欢迎大家在评论区提出问题讨论,笔者看到会第一时间回复,如果觉得对你有帮助的话就点个赞吧。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/851673.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号