spring-beanFactory-创建bean,如何解决循环依赖问题解决办法;【3级缓存使用】

这篇文章有说起飞地址(点我)

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory
AbstractAutowireCapableBeanFactory类
//属性
//未完成的FactoryBean实例缓存:将FactoryBean名称缓存到BeanWrapper
final ConcurrentMap<String,BeanWrapper> factoryBeanInstanceCache = new ConcurrentHashMap<>()
allowCircularReferences = true;//是否允许循环依赖(默认值为true)

//三级缓存
+ (第一级)singletonObjects 缓存的单例bean
+ (第二级)earlySingletonObjects 较早暴露的bean
+ (第三级)singletonFactories ObjectFactory
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
        throws BeanCreationException {
    //【开始实例化bean】Instantiate the bean.
    BeanWrapper instanceWrapper = null;
    //如果beanDefinition定义是单例的话
    if (mbd.isSingleton()) {
        //在缓存未完成的FactoryBean给移除
        instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
    }
    if (instanceWrapper == null) {
        //调用无参构造函数,创建一个bean包装器new Bean();
        instanceWrapper = createBeanInstance(beanName, mbd, args);
    }
    //获取包装器的bean实例
    Object bean = instanceWrapper.getWrappedInstance();
    Class<?> beanType = instanceWrapper.getWrappedClass();
    if (beanType != NullBean.class) {
        mbd.resolvedTargetType = beanType;
    }

    // Allow post-processors to modify the merged bean definition.
    synchronized (mbd.postProcessingLock) {
        if (!mbd.postProcessed) {
            try {
                applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
            }
            catch (Throwable ex) {
                throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                        "Post-processing of merged bean definition failed", ex);
            }
            mbd.postProcessed = true;
        }
    }

    //先缓存singletons,以解决循环依赖问题;就算是通过BeanFactoryAware等生命筹齐触发的【核心】 Eagerly cache singletons to be able to resolve circular references
    //even when triggered by lifecycle interfaces like BeanFactoryAware.
    //1、是否需要较早的暴露单例=earlySingletonExposure
    //1、条件
    //(1)beanDefinition是定义的bean是单例时(spring默认bean就是单例)
    //(2)allowCircularReferences 是否允许循环依赖,默认值为true
    //(3)isSingletonCurrentlyInCreation(beanName) 看看这个bean是否真正创建中【在前面已经将beanName放进去了】
    boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
            isSingletonCurrentlyInCreation(beanName));
    //是否需要提前暴露bean    
    if (earlySingletonExposure) {
        //addSingletonFactory 内部干的事情
        //(1)singletonFactories 中放入ObjectFactory
        //(2)this.singletonFactories.put(beanName, singletonFactory);
        //(3)this.earlySingletonObjects.remove(beanName);
        //(4)this.registeredSingletons.add(beanName);//已注册的单例bean,加入到registeredSingletons中
        ===最终就是把ObjectFactory放到了singletonFactories中,后面要用。很重要
        addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
    }

    // Initialize the bean instance.
    Object exposedObject = bean;
    try {
        //完成bean的属性设置
        populateBean(beanName, mbd, instanceWrapper);
        //初始化bean
        //1、invokeAwareMethods 执行Aware实现类的执行(设置属性等)
        //2、applyBeanPostProcessorsBeforeInitialization--BeanProcessor 前置处理器
        //3、invokeInitMethods 执行自定义的初始化方法;例如:afterPropertiesSet-InitializingBean接口
        //4、applyBeanPostProcessorsAfterInitialization--BeanProcessor 后置处理器 
        exposedObject = initializeBean(beanName, exposedObject, mbd);
    }
    catch (Throwable ex) {
        if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
            throw (BeanCreationException) ex;
        }
        else {
            throw new BeanCreationException(
                    mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
        }
    }
    //如果当前bean被提前暴露了
    if (earlySingletonExposure) {
        //从getSingleton获取提前暴露的bean的实例
        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()) {
                    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 " +
                            "'getBeanNamesForType' with the 'allowEagerInit' flag turned off, for example.");
                }
            }
        }
    }

    // Register bean as disposable.
    try {
        registerDisposableBeanIfNecessary(beanName, bean, mbd);
    }
    catch (BeanDefinitionValidationException ex) {
        throw new BeanCreationException(
                mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
    }

    return exposedObject;
}
+ addSingletonFactory方法     
protected void addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory) {
    //解决多线程问题
    synchronized (this.singletonObjects) {
        //如果已缓存的单例bean中不存在时
        if (!this.singletonObjects.containsKey(beanName)) {
            //singletonFactories中放入ObjectFactory
            this.singletonFactories.put(beanName, singletonFactory);
            //【很重要】移除较早暴露的bean-实例
            this.earlySingletonObjects.remove(beanName);
            //已注册的单例bean,加入到registeredSingletons中
            this.registeredSingletons.add(beanName);
        }
    }
}
+ getSingleton 获取单例方法
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
    // Quick check for existing instance without full singleton lock
    //步骤
    //1、先从缓存的单例-bean中取拿
    Object singletonObject = this.singletonObjects.get(beanName);
    //如果没拿到(证明这个时候我要依赖的bean还没被创建)
    //看看当前单例bean是否被创建中
    if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
        //从当前较早暴露的earlySingletonObjects集合中拿bean(看看是不是提前暴露了)
        singletonObject = this.earlySingletonObjects.get(beanName);
        //如果还不存在,并且 allowEarlyReference是否允许创建较早的依赖--当前bean创建的时候这是false,依赖注入的时候为true
        if (singletonObject == null && allowEarlyReference) {
            synchronized (this.singletonObjects) {
                // Consistent creation of early reference within full singleton lock
                //再次从singletonObjects看看单例bean存在不存在
                singletonObject = this.singletonObjects.get(beanName);
                if (singletonObject == null) {
                    //从当前较早暴露的earlySingletonObjects集合中拿bean(看看是不是提前暴露了)
                    singletonObject = this.earlySingletonObjects.get(beanName);
                    //如果还没拿到,咋整。下面整
                    if (singletonObject == null) {
                        //从addSingletonFactory方法的功能里面设置的singletonFactories去拿(ObjectFactory)
                        ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
                        if (singletonFactory != null) {//如果拿到了
                            //获取bean,相当于调用了getEarlyBeanReference(beanName, mbd, bean)方法【获取bean实例】
                            singletonObject = singletonFactory.getObject();
                            //拿到了就把他放入earlySingletonObjects中
                            this.earlySingletonObjects.put(beanName, singletonObject);
                            //把开始设置的singletonFactories给移除
                            this.singletonFactories.remove(beanName);
                        }
                    }
                }
            }
        }
    }
    return singletonObject;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值