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

Spring 解决循环依赖

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

Spring 解决循环依赖

一. Bean的生命周期

二. 什么是什么是三级缓存

	
	private final Map singletonObjects = new ConcurrentHashMap<>(256);

	
	private final Map earlySingletonObjects = new HashMap<>(16);

	
	private final Map> singletonFactories = new HashMap<>(16);

获取单例bean时

protected Object getSingleton(String beanName, boolean allowEarlyReference) {
		Object singletonObject = this.singletonObjects.get(beanName);
		if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
			synchronized (this.singletonObjects) {
				singletonObject = this.earlySingletonObjects.get(beanName);
				if (singletonObject == null && allowEarlyReference) {
					ObjectFactory singletonFactory = this.singletonFactories.get(beanName);
					if (singletonFactory != null) {
						singletonObject = singletonFactory.getObject();
						this.earlySingletonObjects.put(beanName, singletonObject);
						this.singletonFactories.remove(beanName);
					}
				}
			}
		}
		return singletonObject;
	}

第一步:第一层缓存singletonObjects 中,获取单例bean,拿到了直接使用,没有拿到则拿二级缓存;
第二步:在二级缓存earlySingletonObjects中,提前暴露的Bean;
第三步:在三级缓存中查找对应的工厂对象,利用拿到的工厂对象去获取包装后的bean。

如果不使用三级缓存singletonFactories,无法解决AOP后置增强问题,
多一级缓存意义就是在bean循环引用过程中,发生了AOP增强时,避免返回真实对象而非代理对象Proxy。

三. 为什么用三级缓存不用两级缓存

初始spring是没有解决循环引用问题的,设计原则是 bean 实例化、属性设置、初始化之后 再 生成aop对象,但是为了解决循环依赖但又尽量不打破这个设计原则的情况下,使用了存储了函数式接口的第三级缓存;
如果使用二级缓存的话,可以将aop的代理工作提前到 提前暴露实例的阶段执行; 也就是说所有的bean在创建过程中就先生成代理对象再初始化和其他工作; 但是这样的话,就和spring的aop的设计原则相驳,aop的实现需要与bean的正常生命周期的创建分离; 这样只有使用第三级缓存封装一个函数式接口对象到缓存中, 发生循环依赖时,触发代理类的生成。

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

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

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