您的位置:首页 > 新闻 > 资讯 > Spring源码浅析の循环依赖

Spring源码浅析の循环依赖

2025/3/14 7:28:24 来源:https://blog.csdn.net/2301_77599076/article/details/141831016  浏览:    关键词:Spring源码浅析の循环依赖

AbstractBeanFactory#doGetBean:尝试获取bean

如果bean是单例的:

if (mbd.isSingleton()) {//尝试获取bean <一>sharedInstance = getSingleton(beanName, () -> {try {//获取不到就创建return createBean(beanName, mbd, args);}catch (BeansException ex) {// Explicitly remove instance from singleton cache: It might have been put there// eagerly by the creation process, to allow for circular reference resolution.// Also remove any beans that received a temporary reference to the bean.destroySingleton(beanName);throw ex;}});//然后再次获取bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);...	
}

<一>
DefaultSingletonBeanRegistry#getSingleton 方法
先从单例池中获取:Object singletonObject = this.singletonObjects.get(beanName);
如果获取不到就去创建一个:singletonObject = singletonFactory.getObject(); 实际调用的是AbstractBeanFactory#createBean <二>
然后放入单例池 addSingleton(beanName, singletonObject);

<二>
重点是 Object beanInstance = doCreateBean(beanName, mbdToUse, args);

AbstractAutowireCapableBeanFactory#doCreateBean的逻辑:

  • 实例化对象:AbstractAutowireCapableBeanFactory#createBeanInstance
  • 解决循环依赖:
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");}addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));<>
}

<三>

protected void addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory) {Assert.notNull(singletonFactory, "Singleton factory must not be null");锁单例池,防止并发synchronized (this.singletonObjects) {单例池中找不到当前beanif (!this.singletonObjects.containsKey(beanName)) {在三级缓存中放入 k:当前bean名称 value 工厂this.singletonFactories.put(beanName, singletonFactory);二级缓存删除当前bean的名称this.earlySingletonObjects.remove(beanName);保存当前已经注册单例bean的名称this.registeredSingletons.add(beanName);}}}
  • 属性赋值:AbstractAutowireCapableBeanFactory#populateBean
  • 初始化:AbstractAutowireCapableBeanFactory#initializeBean

循环依赖:A和B两个实例,A的属性是B,B的属性是A
前提条件,A和B都是单例的。假设目前要初始化A:
1、AbstractBeanFactory#doGetBean 尝试获取A
2、获取不到,AbstractBeanFactory#createBean 创建A
 2.1、实例化A
 2.2、解决循环依赖:在三级缓存中放入k:a,V:A的工厂
 2.3、设置属性,发现需要B
  2.3.1、AbstractBeanFactory#doGetBean 尝试获取B
  2.3.2、获取不到,AbstractBeanFactory#createBean 创建B
   2.3.2.1、实例化B
   2.3.2.2、解决循环依赖:在三级缓存中放入k:b,V:B的工厂
   2.3.2.3、设置属性,发现需要A,再次调用AbstractBeanFactory#doGetBean(在AbstractAutowireCapableBeanFactory#autowireByNamegetBean) ,走Object sharedInstance = getSingleton(beanName);<四>
   2.3.2.4、初始化B,DefaultSingletonBeanRegistry#addSingleton 中将B放入一级缓存,删除二级缓存
 2.4、初始化A,DefaultSingletonBeanRegistry#addSingleton 中将A放入一级缓存,删除二级缓存

<四>

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);//根据bean的名称找到bean工厂if (singletonFactory != null) {//创建beansingletonObject = singletonFactory.getObject();//放入二级缓存this.earlySingletonObjects.put(beanName, singletonObject);//从三级缓存中清除this.singletonFactories.remove(beanName);}}}}//返回bean的实例return singletonObject;
}

小结

doGetBean中有两个getSingleton方法,第一个用于解决依赖循环问题,第二个只有一级缓存中没有对应bean的时候,才会调用createBean,实例化,向三级缓存中提前曝光。属性设置,初始化都是在createBean中的

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com