spring-循环依赖源码分析

本次源码分析基于springBoot2.7.12

循环依赖情况如下:

a、A依赖B,B依赖A

//AService依赖BService
@Component
public class AService {
    @Autowired
    private BService bService;
}
//BService依赖AService
@Component
public class BService {
    @Autowired
    private AService aService;
}

b、A依赖A

@Component
public class AService {
    @Autowired
    private AService aService;
}

1、基于a情况

AService的生命周期包括:

1.1、预处理

调用DefaultListableBeanFactory的preInstantiateSingletons方法里的#747#行

this.getBean(beanName);

继续调用AbstractBeanFactory的doGetBean方法里的#205#行

sharedInstance = this.getSingleton(beanName, () -> {
    try {
        return this.createBean(beanName, mbd, args);
    } catch (BeansException var5) {
        ...
    }
});

最终通过DefaultSingletonBeanRegistry的getSingleton方法里的#132#行,实现把beanName放入到singletonsCurrentlyInCreation中,表示AService正在创建中。

this.beforeSingletonCreation(beanName)

具体通过DefaultSingletonBeanRegistry的beforeSingletonCreation方法里的#238#行实现

if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.add(beanName)) {

继续调用AbstractAutowireCapableBeanFactory的createBean方法里的#343#行

 beanInstance = this.doCreateBean(beanName, mbdToUse, args);

通过调用AbstractAutowireCapableBeanFactory的方法doCreateBean里的#385#行,判断此时Aservice正在创建中并且是单例类型

boolean earlySingletonExposure = mbd.isSingleton() && this.allowCircularReferences && this.isSingletonCurrentlyInCreation(beanName);
if (earlySingletonExposure) {
    ...    
    //此时判断AServicesbean定义信息是单例类型&&允许循环依赖&&正在创建中,
    //那么会把AbstractAutowireCapableBeanFactory的getEarlyBeanReference方法以lamda表达式的方式存储到singletonFactories中
    this.addSingletonFactory(beanName, () -> {
         return this.getEarlyBeanReference(beanName, mbd, bean);
    });
}

具体通过DefaultSingletonBeanRegistry的addSingletonFactory方法里的#78#行实现把lamda表达式存储到singletonFactories中

this.singletonFactories.put(beanName, singletonFactory);

,1.2、加载类,1.3、实例化前,1.4、实例化,1.5、实例化后,1.6、属性赋值

此时AService属性赋值,获取BService bean对象,需要执行Bservice生命周期过程,

1.7、初始化前,1.8、初始化,1.9、初始化后,2.0、放入singletonObjects

BService的生命周期包括:

1.1、预处理,1.2、加载类,1.3、实例化前,1.4、实例化,1.5、实例化后,1.6、属性赋值

此时BService属性赋值,获取AService bean对象,此时会通过singletonFactories获取lamda表达式提前创建对象Aservice,并放入到earlySingletonObjects中,注意:此时的Aservice对象并不是完整的生命周期,并且AService可能是原始对象或代理对象。

具体如下:

调用DefaultListableBeanFactory的preInstantiateSingletons方法里的#747#行

this.getBean(beanName);

继续调用AbstractBeanFactory的doGetBean方法里的#134#行,通过this.isSingletonCurrentlyInCreation(beanName)判断AService正在创建中&&allowEarlyReference=true&&单例池中AService为空,那么就通过lamda表达式创建非完整生命周期的Aservice对象,注意:AService对象可能是原始对象或代理对象,并放入到earlySingletonObjects中。

protected Object getSingleton(String beanName, boolean allowEarlyReference) {
        Object singletonObject = this.singletonObjects.get(beanName);
         //判断beanName正在创建中
        if (singletonObject == null && this.isSingletonCurrentlyInCreation(beanName)) {
            singletonObject = this.earlySingletonObjects.get(beanName);
            //单例池中不存在单例,并且allowEarlyReference为true
            if (singletonObject == null && allowEarlyReference) {
                Map var4 = this.singletonObjects;
                synchronized(this.singletonObjects) {
                    singletonObject = this.singletonObjects.get(beanName);
                    if (singletonObject == null) {
                        singletonObject = this.earlySingletonObjects.get(beanName);
                        if (singletonObject == null) {
                            //获取singletonFactories中的lamda表达
                            ObjectFactory<?> singletonFactory = (ObjectFactory)this.singletonFactories.get(beanName);
                            if (singletonFactory != null) {
                                //创建非完成生命周期的原始或代理对象,并放入earlySingletonObjects中
                                singletonObject = singletonFactory.getObject();
                                this.earlySingletonObjects.put(beanName, singletonObject);
                                //移除singletonFactories中对应的表达式
                                this.singletonFactories.remove(beanName);
                            }
                        }
                    }
                }
            }
        }
        return singletonObject;
}

具体执行的lamda表达式是AbstractAutowireCapableBeanFactory的getEarlyBeanReference方法里的#657#行

for(Iterator var5 = this.getBeanPostProcessorCache().smartInstantiationAware.iterator(); var5.hasNext(); exposedObject = bp.getEarlyBeanReference(exposedObject, beanName)) {

  具体通过AbstractAutoProxyCreator 的getEarlyBeanReference方法里的#115#行实现

return this.wrapIfNecessary(bean, beanName, cacheKey);

  实例化后,则通过earlyProxyReferences判断Bservice是否提前创建了bean,是则不再执行实例化后操作,直接返回原始对象。

public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
        if (bean != null) {
            Object cacheKey = this.getCacheKey(bean.getClass(), beanName);
            //判断是否提前创建了对象
            if (this.earlyProxyReferences.remove(cacheKey) != bean) {
                return this.wrapIfNecessary(bean, beanName, cacheKey);
            }
        }
        return bean;
}

最后再次判断当前类是单例&&allowCircularReferences为true&&正在创建中,那么则通过AbstractAutowireCapableBeanFactory的doCreateBean里的#413#行把earlySingletonObjects中的bean对象赋值给最终单例对象 

if (earlySingletonExposure) {
            Object earlySingletonReference = this.getSingleton(beanName, false);
            if (earlySingletonReference != null) {
                if (exposedObject == bean) {
                    exposedObject = earlySingletonReference;

最终再通过AbstractBeanFactory的doGetBean方法里的#205#行,把AService放到singletonObjects中

sharedInstance = this.getSingleton(beanName, () -> {
    try {
        return this.createBean(beanName, mbd, args);
    } catch (BeansException var5) {
        this.destroySingleton(beanName);
        throw var5;
    }
});

1.7、初始化前,1.8、初始化,1.9、初始化后,2.0、放入singletonObjects

 
总结:解决循环依赖主要通过三级缓存
singletonObjects:存储的完整的生命周期的对象,也就是单例池
earlySingletonObjects:存储的非完整生命周期的原始对象或代理对象 
singletonFactories:存储创建非完整生命周期的lamda表达式

singletonsCurrentlyInCreation:判断当前bean是否正在创建中

earlyProxyReferences:判断当前bean是否被提前创建

posted @ 2023-07-16 16:05  西风51668  阅读(184)  评论(0)    收藏  举报