spring循环依赖解决方案

https://www.bilibili.com/video/BV1KK4y1L7Kf?p=23 视频地址总结

问题:

通常说被spring管理的对象,我们叫做Bean

1、扫描类得到-->BeanDefinition(bean定义)

2、基于class--new class //原始对象

3、填充属性

4、Aware

5、初始化

6、BeanProcessor(bean的后置处理器)

7、AOP

8、放入单例池

第四步填充属性:

A需要B,然后B需要A,这种就叫做循环依赖

针对这种情况,spring是如何解决这种循环依赖问题的。

AbstractAutowireCapableBeanFactory里面的doCreateBean方法里面,创建Bean
// Eagerly cache singletons to be able to resolve circular references
// even when triggered by lifecycle interfaces like BeanFactoryAware.

BeanDefinition=mdb
mbd.isSingleton()看看当前创建的这个bean定义里面是不是单例
allowCircularReferences 是否允许循环依赖(引用),这个是一个参数默认值为true,
isSingletonCurrentlyInCreation(beanName)看看当前bean是否在创建中
属性singletonsCurrentlyInCreation为Set集合--里面存放的是,正在创建的bean
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
      isSingletonCurrentlyInCreation(beanName));
//如果都满足
if (earlySingletonExposure) {
   if (logger.isTraceEnabled()) {
      logger.trace("Eagerly caching bean '" + beanName +
            "' to allow for resolving potential circular references");
   }
   //将当前创建的bean提前暴露出来ObejctFactory--这里为什么说是提前暴露,继续看下面代码
   addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}

//跟上面的条件一样
if (earlySingletonExposure) {
    //在此从取一下要创建的对象--下面看看getSingleton的源码
	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<>(dependentBeans.length);
			for (String dependentBean : dependentBeans) {
				if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
					actualDependentBeans.add(dependentBean);
				}
			}
			if (!actualDependentBeans.isEmpty()) {
				//这里是抛的异常,代码省略
			}
		}
	}
}

//实现原理
1、首先从一级缓存(singletonObjects缓存里面去拿)
2、如果没有,就从earlySingletonObjects去拿(二级缓存)
3、如果还没有,就从singletonFactory.getObject()(三级缓存)去拿
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
	// Quick check for existing instance without full singleton lock
	Object singletonObject = this.singletonObjects.get(beanName);
	if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
		singletonObject = this.earlySingletonObjects.get(beanName);
		if (singletonObject == null && allowEarlyReference) {
			synchronized (this.singletonObjects) {
				// Consistent creation of early reference within full singleton lock
				singletonObject = this.singletonObjects.get(beanName);
				if (singletonObject == null) {
					singletonObject = this.earlySingletonObjects.get(beanName);
					if (singletonObject == null) {
						ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
						if (singletonFactory != null) {
                            //这个就拿到的一个代理对象
							singletonObject = singletonFactory.getObject();
							this.earlySingletonObjects.put(beanName, singletonObject);
							this.singletonFactories.remove(beanName);
						}
					}
				}
			}
		}
	}
	return singletonObject;
}


这里做了几个事情
1、singletonObjects一级缓存里面不包含当前创建的beanName(包含就表示已经创建好了)
2、earlySingletonObjects三级缓存
3、singletonFactories二级缓存
protected void addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory) {
		Assert.notNull(singletonFactory, "Singleton factory must not be null");
		synchronized (this.singletonObjects) {
			if (!this.singletonObjects.containsKey(beanName)) {
				this.singletonFactories.put(beanName, singletonFactory);
				this.earlySingletonObjects.remove(beanName);
				this.registeredSingletons.add(beanName);
			}
		}
}

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值