Spring之循环依赖注入

本文深入探讨了Spring框架中处理循环依赖的机制。通过实例化、填充属性和初始化的步骤,详细解释了如何利用三级缓存singletonFactories解决循环引用问题。在bean实例化后,尚未填充属性时会放入该缓存,以便于其他bean获取引用,从而在属性填充过程中递归创建并解决循环依赖。整个过程展示了Spring在处理复杂依赖关系时的灵活性和智能性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在之前的博客中我们已经多次提到了循环引用,但是都没有细讲,就是希望可以单独拿出来看一下。下面就开始吧!
首先创建了循环引用的三个类,他们的引用关系如下图:
在这里插入图片描述
在客户端调用效果如下图:
在这里插入图片描述
开始啃源码吧!之前讲过的代码我们就不贴,只放我们之前没讲的代码,其他代码一带而过,直接到bean实例化后填充属性:

protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
		...
		//里面有一个classRoom属性值,classRoom还没有实例化
		PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);
		...
		if (pvs != null) {
			applyPropertyValues(beanName, mbd, bw, pvs);
		}
	}

在这我们还要注意一点,当一个bean实例化完,还没有填充属性的时候,它会被放到singletonFactories这个三级缓存中,在我看来,主要是为了解决循环引用问题,通过分析后面的代码我们会更加清晰这样做的目的。
这个方法里面我们关注的只有上面这些代码,一个是获取要实例化的bean的要填充的属性值,另外就是开始填充属性,在这里,只有一个属性要填充,就是classRoom,但是他还没有被实例化,我们看接下来是怎么处理的。

protected void applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs) {
		//判断有没有需要填充的属性
		if (pvs.isEmpty()) {
			return;
		}

		MutablePropertyValues mpvs = null;
		List<PropertyValue> original;
		...
		if (pvs instanceof MutablePropertyValues) {
			mpvs = (MutablePropertyValues) pvs;
			//需要填充的属性有没有被转换成指定的类型
			if (mpvs.isConverted()) {
				try {
					bw.setPropertyValues(mpvs);
					return;
				}
				catch (BeansException ex) {
					...
				}
			}
			//属性值没有被转换,需要进行类型转换
			original = mpvs.getPropertyValueList();
		}
		else {
			original = Arrays.asList(pvs.getPropertyValues());
		}

		TypeConverter converter = getCustomTypeConverter();
		if (converter == null) {
			converter = bw;
		}
		//得到一个类型转换器,在本文要讲的循环引用的解决他是核心
		BeanDefinitionValu
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值