spring解决循环依赖 (总结)

spring bean如何解决循环依赖?
描述一下流程
	首先ab两个互相依赖
	假设先创建a,设置属性之前 调用了这个方法
	addSingletonFactory(beanName, new ObjectFactory<Object>() {
			@Override
			public Object getObject() throws BeansException {
				return getEarlyBeanReference(beanName, mbd, bean);
			}
		});
	 放入三级缓存,并二级缓存中取出	在设置属性的时候会调用后置处理器 auto 开始注入b  
	b开始实例华并创建,同样在设置属性的时候调用后置处理器开始注入a
	同样的流程 但是在dogetbean开始获取单例的方法时候 发现了三级缓存中存在a了 拿到a返回 直接给他放到二级缓存中就好了 同时清掉三级缓存

这里不同的地方 属性注入时候调用了 return getSingleton(beanName, true); 注意这个值为true 代表了从可以三级缓存中获取这个地方不得不说设计的很精妙

有个大坑 循环依赖的时候会有异步方法的时候 会报错 原因是 调用后置处理器之后发现对象被他们代理过
下面会有个比较元对象是否等于二级缓存中的 但是因为a存在异步 已经被后置处理代理过了 会发现根本不相等
在底下判断的时候又发现a存在被b依赖的现象 就是抛出异常

加入没有存在循环依赖的话 在判断中从getSingleton的时候二级缓存也没有 这时候传入的还是false 并不会去三级缓存中获取,这个时候发现得不到对象 直接return就好了 最后会执行addSingleton 这个时候清掉三级缓存 清掉二级缓存 放入一级缓存中去

	if (earlySingletonExposure) {
			Object earlySingletonReference = getSingleton(beanName, false);
			if (earlySingletonReference != null) {
				if (exposedObject == bean) {
					exposedObject = earlySingletonReference;
				}
				else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
					String[] dependentBeans = getDependentBeans(beanName);
					Set<String> actualDependentBeans = new LinkedHashSet<String>(dependentBeans.length);
					for (String dependentBean : dependentBeans) {
						if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
							actualDependentBeans.add(dependentBean);
						}
					}
					if (!actualDependentBeans.isEmpty()) {
						throw new BeanCurrentlyInCreationException(beanName,
								"Bean with name '" + beanName + "' has been injected into other beans [" +
								StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +
								"] in its raw version as part of a circular reference, but has eventually been " +
								"wrapped. This means that said other beans do not use the final version of the " +
								"bean. This is often the result of over-eager type matching - consider using " +
								"'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example.");
					}
				}
			}
		}

至此 循环依赖全部解决
解决方案:加@lazy 注意在注入的属性上加
目前公司实现方案:不开启异步,自己实现注解

详细见: Spring是如何利用"三级缓存"巧妙解决Bean的循环依赖问题的
作者:YourBatman

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值