【spring源码】八、循环依赖(重要)

【八】Spring IoC 最全源码详解之bean的循环依赖 先有鸡还是先有蛋,这是一个问题。 目录 1. 什么是循环依赖 2. Spring针对循环依赖的解决方案 2.1 亚当的登场 2.2 夏娃的诞生 2.3 寻找亚当 2.4 完成亚当的创建 3. 附录:本项目工程文件 1. 什么是循环依赖 你中有我,我中有你,就是循环依赖。举个例子,本文使用的项目中“yadang”与“xiawa”这两个bean就是循环依赖的(参考附录)。Cla... 阅读详情
流程预览

getBean(A),A调用完构造方法后,将A的工厂放入singletonFactories。属性需要注入B,B又需要注入A,又去getBean(A)时,调用了getSingleton1(),然后从工厂中获取并且提前代理了, 把提前代理好的放入earlyProxyReferences,这样B.A就注入好了。

B创建完,A的属性A.B也注入好了,A执行初始化方法,调用applyBeanPostProcessorsAfterInitialization的时候发现之前提前代理过了,所以不重复代理了。

而上面的逻辑其实是在getBean(A)的doGetBean(A)的getSingleton的singletonFactory.getObject();的createBean()逻辑里,而在getSingleton里,执行完getObject后,还有一个addSingleton(beanName, singletonObject);,就是在这里添加到单例池中,并且从其他级中删除

img

什么叫循环依赖

A有属性B需要注入,B有属性A需要注入。

或者A有属性B,B有属性C,C有属性A

A BC B有A 然后创建C

循环依赖分析

别管几级map了,各个地方说法不一样

A有属性B,所以getBean(A)的时候又去getBean(B),但是因为B有属性A,又去getBean(A)的时候,我们应该能从单例池中直接拿到A(误,其实是从早期单例吃和早期对象工厂中)。

看似只有一个单例池就好了,即使没有属性注入,只要执行完构造函数就可以放入单例池中?B对象拿到就可以了?

但是A还没有创建完成,单例池必须是创建完的才能放入,所以我们需要另外一个map。

我们把map叫做earlySingletonObjects,存放早期对象或提前代理对象(即对象最新的)

isSingletonCurrentlyInCreation:一旦一个bean开始创建,那么就把他放入【正在创建集合isSingletonCurrentlyInCreation】中,直到最后一步再从【正在创建集合】中移除,放入单例池。这样我们就可以通过他判断是否需要提前代理(或者说还是第一次getBean这个类)

二级map可能是没有原始问题的,但是有动态代理的问题。

A有属性B,B有属性AC,C有属性A,他们都判断A需要被代理,而判断到A正在创建后他们都拿A的原始动态去包装代理,那BC都创建了各自的一个A代理对象。所以我们在判断到A需要进行AOP的时候,我们就提前进行AOP,然后返回他的代理对象放到earlySingletonObjects中。

如何提前代理?我们直接传入bean工厂,这个工厂就能帮我们创建代理对象,也可以创建普通bean,完全依赖于isSingletonCurrentlyInCreation

提前AOP的问题

提前AOP的时机:执行完构造函数就直接AOP吗?另外在最后AOP之前,判断一下是否提前进过AOP了,进行过了就不要重复AOP了

怎么判断有循环依赖:通过isSingletonCurrentlyInCreation且有切面 判断

提前AOP完能直接放到单例池吗?属性还是没有值,bean不完整。还是得在earlySingletonObjects中

所以我们应该再有个动态代理的map,getBean的时候先看是不是在创建中,然后判断

重申3级map的作用
  • singletonObjects:这个无需讲,就是单例吃
  • earlySingletonObjects:这个一般都为空,只有代理过了才不为空,也就是说他存放的是代理对象
  • singletonFactory:它提供了把原生对象代理的方法,要发生代理的话通过它的getObject()就生成代理对象了,生成之后放入earlySingletonObjects中就可以了

getBean

doGetBean

在这里面,首先调用了transformedBeanName给bean名字转了一个name

然后调用

Object sharedInstance = getSingleton(beanName);

注意我们有两个重载的getSingleton

// 1
getSingleton(String beanName, boolean allowEarlyReference);
// 2 
getSingleton(String beanName, ObjectFactory<?> singletonFactory) 

我们在这里调用的是第一个getSingleton

第一个getSingleton
protected Object getSingleton(String beanName, boolean allowEarlyReference) {

    // 1 检查单例池中是否有,拿不到
    Object singletonObject = this.singletonObjects.get(beanName);
    // 单例池中没有,是否在创建中?我们在这里还没有在这个集合中add过,所以也不在创建中,不进入if,返回null
    if (singletonObject == null &&  //double check
        isSingletonCurrentlyInCreation(beanName)) { // 没有正在创建中,不进入
        ...;
    }
    return singletonObject;

回到了doGetBean

protected <T> T doGetBean(
    final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly)throws BeansException {

    final String beanName = transformedBeanName(name);
    Object bean;
    // 从这里退出来了
    Object sharedInstance = getSingleton(beanName);
    // 没拿到,进入else
    if (sharedInstance != null && args == null) {
        bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
    }
    else {
        
       // 如果是原型而正在创建中,我们不是,跳过
        if (isPrototypeCurrentlyInCreation(beanName)) {
            throw new BeanCurrentlyInCreationException(beanName);
        }

        // 判断bd是否在父工厂中(父功能中有就不创建了)
        BeanFactory parentBeanFactory = getParentBeanFactory();
        // 如果beanDefinitionMap中也就是在所有一级加载的类中不包括beanName则尝试从parentBeanFactory中检测
        if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
            // Not found -> check parent.
            String nameToLookup = originalBeanName(name);
            // 递归到beanFactory中寻找
            if (args != null) {
                // Delegation to parent with explicit args.
                return (T) parentBeanFactory.getBean(nameToLookup, args);
            }
            else {
                // No args -> delegate to standard getBean method.
                return parentBeanFactory.getBean(nameToLookup, requiredType);
            }
        }

        // 在这里把当前bean名字添加到了集合alreadyCreated中
        if (!typeCheckOnly) {
            markBeanAsCreated(beanName);//内部是alreadyCreated.add(beanName);
        }
        
        try {
            // 将存储XML配置文件的GernericBeanDefinition转换为RootBeanDefinition,如果指定beanName是子bean的话同时会合并父类的相关属性
            final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
            checkMergedBeanDefinition(mbd, beanName, args);

            // Guarantee initialization of beans that the current bean depends on.
            String[] dependsOn = mbd.getDependsOn();
            // 先注册依赖的bean,这里不重点分析
            if (dependsOn != null) {
                for (String dep : dependsOn) {
                    if (isDependent(beanName, dep)) {throw ...;}
                    registerDependentBean(dep, beanName);// 缓存依赖调用
                    getBean(dep);
                }
            }
            // 如果bean是单例的
            if (mbd.isSingleton()) {
                // 调用第二个getSingleton
                sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() {//从这里进入getSingleton,并传入一个工厂
                    @Override // getObject()里调用了createBean()
                    public Object getObject() throws BeansException {
                        try {
                            return createBean(beanName, mbd, args);
                        } catch (BeansException ex) { 。。。; }
                    }
                });
                // 同上
                bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
            }else if (mbd.isPrototype()) {//多例的

我们看到从单例池中没拿到,也没在创建中,又看到bd是单例的,就去调用第二个getSingleton,他的第二个参数利用lambda表达式传入了一个bean工厂,意思是一旦执行该bean工厂对象.getObject(),就会调用createBean()

我们进入第二个getSingleton

放入singletonsCurrentlyInCreation
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
    Assert.notNull(beanName, "'beanName'不能为空");
    // 锁住单例池
    synchronized (this.singletonObjects) {// 全局变量需要同步
        // 从单例池中获取,拿不到
        Object singletonObject = this.singletonObjects.get(beanName);
        // 进入
        if (singletonObject == null) {
            if (this.singletonsCurrentlyInDestruction) {throw("正在销毁异常")...;}
            
            // 在里面把当前beanName加入到singletonsCurrentlyInCreation正在创建集合中
            beforeSingletonCreation(beanName); 
            /* 看一下这个方法的源码
            beforeSingletonCreation(beanName){
                if (!this.inCreationCheckExclusions.contains(beanName) &&  // 判断当前需要创建的bean是否在Exclusions集合,被排除的bean,程序员可以提供一些bean不被spring初始化(哪怕被扫描到了,也不初始化),那么这些提供的bean便会存在这个集合当中;
                	!this.singletonsCurrentlyInCreation.add(beanName)) { //如果当前bean不在排除的集合当中那么则这个bean添加到(当然这里只是把bean名字添加到集合,为了方便我们直接认为把bean添加到集合吧,因为他能根据名字能找打对应的bean)
                	
                    throw new BeanCurrentlyInCreationException(beanName);
				}
            }
            */
            boolean newSingleton = false;
            boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
            if (recordSuppressedExceptions) {
                this.suppressedExceptions = new LinkedHashSet<Exception>();
            }
            try {
                // getObject(),里面调用createBean()
                singletonObject = singletonFactory.getObject();//工厂//调用传进来工厂的getObject()方法
createBean
// 
protected Object createBean(String beanName, RootBeanDefinition mbd, Object[] args) throws BeanCreationException {

    RootBeanDefinition mbdToUse = mbd;

    // Make sure bean class is actually resolved at this point, and
    // clone the bean definition in case of a dynamically resolved Class
    // which cannot be stored in the shared merged bean definition.
    Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
    if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
        mbdToUse = new RootBeanDefinition(mbd);
        mbdToUse.setBeanClass(resolvedClass);
    }

    // Prepare method overrides.
    try {
        mbdToUse.prepareMethodOverrides();
    }catch (BeanDefinitionValidationException ex) {
        throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),beanName, "Validation of method overrides failed", ex);
    }

    try {
        // Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
        // 给实例化后置处理器一个返回代理对象的机会
        Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
        if (bean != null) {
            return bean;
        }
    }catch (Throwable ex) {
        throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName, "BeanPostProcessor before instantiation of bean failed", ex);
    }

    // 前面后置处理器没有返回代理对象,我们创建正常的普通对象
    Object beanInstance = doCreateBean(beanName, mbdToUse, args);

    return beanInstance;
}
doCreateBean
// AbstractAutowireCapableBeanFactory
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
    throws BeanCreationException {

    // Instantiate the bean.
    BeanWrapper instanceWrapper = null;
    if (mbd.isSingleton()) {
        instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);// 移除缓存
    }
    if (instanceWrapper == null) {
        // doCreateBean-1 
        // 仅仅完成了对象创建,剩下都没做 // 将bd转换成BeanWrapper
        instanceWrapper = createBeanInstance(beanName, mbd, args);
    }
    // 从Wrapper中获取原始对象,这个时候这个bean就有地址值了,就能被引用了
    final 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;
        }
    }

    // 是否允许提前暴露,
    boolean earlySingletonExposure = (mbd.isSingleton() && 
                                      this.allowCircularReferences &&
                                      isSingletonCurrentlyInCreation(beanName));// 在前面加进去了
    // 允许提交暴露,就放入singletonFactory中,只不过这个factory是返回代理对象用的
    if (earlySingletonExposure) {
        addSingletonFactory(beanName,
                            new ObjectFactory(){
                                public Object getObject() throws BeanException{
                                    return getEarlyBeanReference(beanName, mbd, bean));
                                }
                            });
    }
放入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)) {
            // 把传入的单例工厂放入singletonFactories
            this.singletonFactories.put(beanName, singletonFactory);
            // 本来也还没有,不用remove
            this.earlySingletonObjects.remove(beanName);
            this.registeredSingletons.add(beanName);
        }
    }
}

可以发现虽然传入了单例工厂,并没有执行,只是放入了集合中singletonFactories。然后回到doCreateBean,我们放下看

属性注入
// AbstractAutowireCapableBeanFactory
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
    throws BeanCreationException {

    // Instantiate the bean.
    BeanWrapper instanceWrapper = null;
    if (mbd.isSingleton()) {
        instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);// 移除缓存
    }
    if (instanceWrapper == null) {
        // doCreateBean-1 
        // 仅仅完成了对象创建,剩下都没做 // 将bd转换成BeanWrapper
        instanceWrapper = createBeanInstance(beanName, mbd, args);
    }
    // 从Wrapper中获取原始对象,这个时候这个bean就有地址值了,就能被引用了
    final 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;
        }
    }

    // 是否允许提前暴露,
    boolean earlySingletonExposure = (mbd.isSingleton() && 
                                      this.allowCircularReferences &&
                                      isSingletonCurrentlyInCreation(beanName));// 在前面加进去了
    // 进入
    if (earlySingletonExposure) {
        addSingletonFactory(beanName,
                            new ObjectFactory(){
                                public Object getObject() throws BeanException{
                                    return getEarlyBeanReference(beanName, mbd, bean));
                                }
                            });
    }
    
    // 原始对象
    Object exposedObject = bean;
    try {
        // 属性填充
        populateBean(beanName, mbd, instanceWrapper);

属性填充,可想而已里面肯定又要有B的bean,所以去创建B,B又发现由依赖A,又去getBean(A)

//public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport implements ConfigurableBeanFactory {
protected <T> T doGetBean(
    final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly)throws BeansException {

    final String beanName = transformedBeanName(name);
    Object bean;
    // 又进入第一个getSingleton
    Object sharedInstance = getSingleton(beanName);//重载getSingleton(beanName, true);//这时没有传入工厂

又一次getSingleton1
public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements SingletonBeanRegistry {

    // 程序员一般从这个getSingleton中就能得到bean。但在注册容器的时候是拿不到的,除非有单例循环依赖
    protected Object getSingleton(String beanName, boolean allowEarlyReference) {

        // 单例池中没有
        Object singletonObject = this.singletonObjects.get(beanName);

        // 进入if
        if (singletonObject == null &&  //double check
            isSingletonCurrentlyInCreation(beanName)) {

            // 锁住单例池
            synchronized (this.singletonObjects) {
                // 2 从earlySingletonObjects中获取,我们还没放入过,拿不到(放入的是singletonFactory)
                singletonObject = this.earlySingletonObjects.get(beanName); // 循环依赖我们的最终目的是放到earlySingletonObjects里
                // 在early中没拿到,去执行工厂的方法
                if (singletonObject == null && allowEarlyReference) {
                    // 3 前面放入过singletonFactories,所以拿到了singletonFactory
                    ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
                    if (singletonFactory != null) {
                        // 调用前面传入的工厂lambda函数的方法,getObject()里有getEarlyBeanReference(beanName, mbd, bean));所以发生了代理
                        singletonObject = singletonFactory.getObject();
                        // 执行完把代理对象或原生对象放入了earlySingletonObjects
                        this.earlySingletonObjects.put(beanName, singletonObject);
                        this.singletonFactories.remove(beanName);
                    }
                }
            }
        }
        return singletonObject;
    }

至此我们知道earlySingletonObjects放入了代理对象,这个单词的early代表的是早点放入代理,而非原生对象

提前代理getEarlyBeanReference
protected Object getEarlyBeanReference(String beanName,
                                       RootBeanDefinition mbd,
                                       Object bean) {
    
    // 传入原始对象,经过代理后返回,无需代理就不代理返回
    Object exposedObject = bean;
    // 我们的后置处理器就是实现了该接口InstantiationAwareBeanPostProcessors
    if (!mbd.isSynthetic()  // 异步
        && hasInstantiationAwareBeanPostProcessors()) { // 
        
        // 遍历符合要求的后置处理器
        for (BeanPostProcessor bp : getBeanPostProcessors()) {
            // 找到动态代理的后置处理器
            if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
                // 转换类型
                SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp;//SmartInstantiationAwareBeanPostProcessor这个接口要求重写getEarlyBeanReference方法
                // 拿到代理对象
                exposedObject = ibp.getEarlyBeanReference(exposedObject, beanName);
            }
        }
    }
    // 返回代理对象
    return exposedObject;
}

上面有一个getEarlyBeanReference(exposedObject, beanName);就是发生代理的地方,我们取看看

放入earlyProxyReferences

放入earlyProxyReferences并提前代理。如果没有代理过,就不会放入earlyProxyReferences。这个集合存放的是原生对象

public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport
    implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware {
    
    public Object getEarlyBeanReference(Object bean, String beanName) {
        // 用类和name组合一个key
        Object cacheKey = getCacheKey(bean.getClass(), beanName);
        // 放入集合,放入的是原生对象
        this.earlyProxyReferences.put(cacheKey, bean);
        // 返回代理好的对象
        return wrapIfNecessary(bean, beanName, cacheKey);
    }

我们不细究了, 我们到这里知道代理好了就行,然后我们回到getSingleton1

提前代理放入earlySingletonObjects,移除singletonFactories

回到getSingleton1,提前代理的对象放入earlySingletonObjects。然后把singletonFactories移除

protected Object getSingleton(String beanName, boolean allowEarlyReference) {

    // 1 单例池没有
    Object singletonObject = this.singletonObjects.get(beanName);
    if (singletonObject == null &&  isSingletonCurrentlyInCreation(beanName)) {
        // 锁住单例池
        synchronized (this.singletonObjects) {
            // 2 从earlySingletonObjects中获取,我们还没放入过,拿不到
            singletonObject = this.earlySingletonObjects.get(beanName); 
            // 在early中没拿到,去执行工厂的方法
            if (singletonObject == null && allowEarlyReference) {
                // 3 前面放入过singletonFactories,所以拿到了singletonFactory
                ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
                // 进入
                if (singletonFactory != null) {
                    // 调用前面传入的工厂lambda函数的方法,主要是getEarlyBeanReference(beanName, mbd, bean));
                    singletonObject = singletonFactory.getObject();
                    // 执行完把代理对象或原生对象放入了earlySingletonObjects
                    this.earlySingletonObjects.put(beanName, singletonObject);
                    // 从中singletonFactories移除
                    this.singletonFactories.remove(beanName);
                }
            }
        }
    }
    // 返回提前代理好的对象
    return singletonObject;
}

B.A属性注入好了。然后创建好了B(B的初始化流程没什么特别的,直接说A的初始化流程)

创建好了B,这样A的属性A.B也注入好了,开始执行A的初始化方法。

doCreateBean
// AbstractAutowireCapableBeanFactory
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
    throws BeanCreationException {

    // Instantiate the bean.
    BeanWrapper instanceWrapper = null;
    if (mbd.isSingleton()) {
        instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);// 移除缓存
    }
    if (instanceWrapper == null) {
        // doCreateBean-1 
        // 仅仅完成了对象创建,剩下都没做 // 将bd转换成BeanWrapper
        instanceWrapper = createBeanInstance(beanName, mbd, args);
    }
    // 从Wrapper中获取原始对象,这个时候这个bean就有地址值了,就能被引用了
    final Object bean = instanceWrapper.getWrappedInstance();
    Class<?> beanType = instanceWrapper.getWrappedClass();
    if (beanType != NullBean.class) {
        mbd.resolvedTargetType = beanType;
    }

    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;
        }
    }

    // 是否允许提前暴露,
    boolean earlySingletonExposure = (mbd.isSingleton() && 
                                      this.allowCircularReferences &&
                                      isSingletonCurrentlyInCreation(beanName));// 在前面加进去了
    // 进入,只是添加了个工厂,没有执行里面的方法
    if (earlySingletonExposure) {
        addSingletonFactory(beanName,
                            new ObjectFactory(){
                                public Object getObject() throws BeanException{
                                    return getEarlyBeanReference(beanName, mbd, bean));
                                }
                            });
    }


    // A原始对象
    Object exposedObject = bean;
    try {
        // 属性填充,我们执行完了
        populateBean(beanName, mbd, instanceWrapper);
        // doCreateBean-4 //调用初始化方法,如Aware、before-init后置处理器、init-method、after-init后置处理器
        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);
        }
    }

在init方法中要发生代理,因为已经代理过了,所以得在里面判断一下,判断代理过了在init中就不代理了,防止重复代理

initializeBean

调用before-init、init、after-init方法,前两个不分析了,基本都会执行,直接看最后一个

// AbstractAutowireCapableBeanFactory
protected Object initializeBean(final String beanName, 
                                final Object bean, 
                                @Nullable RootBeanDefinition mbd) {
    if (System.getSecurityManager() != null) {
        AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
            invokeAwareMethods(beanName, bean);
            return null;
        }, getAccessControlContext());
    }
    else {
        invokeAwareMethods(beanName, bean);
    }

    Object wrappedBean = bean;
    if (mbd == null || !mbd.isSynthetic()) {
        // 调用before-init方法
        wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
    }

    try {
        // 调用init方法
        invokeInitMethods(beanName, wrappedBean, mbd);
    }
    catch (Throwable ex) {
        throw new BeanCreationException(
            (mbd != null ? mbd.getResourceDescription() : null),
            beanName, "Invocation of init method failed", ex);
    }
    if (mbd == null || !mbd.isSynthetic()) {
        // 调用after-init方法
        wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
    }

    return wrappedBean;
}
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
    if (bean != null) {
        Object cacheKey = getCacheKey(bean.getClass(), beanName);
        // 看看早期代理引用里有没有,很明显,前面我们因为有循环依赖,该集合中有,所以不代理了,返回返回当前原始bean,这个原始bean会被代理使用
        // 之前放入了原生对象,所以这里不进入了
        if (this.earlyProxyReferences.remove(cacheKey) != bean) {
            return wrapIfNecessary(bean, beanName, cacheKey);
        }
    }
    return bean;
}

执行完init,回到doCreateBean

doCreateBean
// AbstractAutowireCapableBeanFactory
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
    throws BeanCreationException {

    // Instantiate the bean.
    BeanWrapper instanceWrapper = null;
    if (mbd.isSingleton()) {
        instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);// 移除缓存
    }
    if (instanceWrapper == null) {
        // doCreateBean-1 
        // 仅仅完成了对象创建,剩下都没做 // 将bd转换成BeanWrapper
        instanceWrapper = createBeanInstance(beanName, mbd, args);
    }
    // 从Wrapper中获取原始对象,这个时候这个bean就有地址值了,就能被引用了
    final Object bean = instanceWrapper.getWrappedInstance();
    Class<?> beanType = instanceWrapper.getWrappedClass();
    if (beanType != NullBean.class) {
        mbd.resolvedTargetType = beanType;
    }

    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;
        }
    }

    // 是否允许提前暴露,
    boolean earlySingletonExposure = (mbd.isSingleton() && 
                                      this.allowCircularReferences &&
                                      isSingletonCurrentlyInCreation(beanName));// 在前面加进去了
    // 进入,只是添加了个工厂,没有执行里面的方法
    if (earlySingletonExposure) {
        addSingletonFactory(beanName,
                            new ObjectFactory(){
                                public Object getObject() throws BeanException{
                                    return getEarlyBeanReference(beanName, mbd, bean));
                                }
                            });
    }


    // A原始对象
    Object exposedObject = bean;
    try {
        // 属性填充,我们执行完了
        populateBean(beanName, mbd, instanceWrapper);
        // doCreateBean-4 //调用初始化方法,如Aware、before-init后置处理器、init-method、after-init后置处理器
        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) {
        // 从earlySingletonObjects中获得了提前代理好的对象 // getSingleton1
        Object earlySingletonReference = getSingleton(beanName, false);
        // 进入
        if (earlySingletonReference != null) {
            // bean是原始对象,exposedObject是bean经过初始化之后的对象(没代理)。
            if (exposedObject == bean) {//如果在本init方法中没有代理过,
                // 要用exposedObject代表代理的对象,而earlySingletonReference恰好就是被提前代理对象的引用,所以拿他赋值即可
                exposedObject = earlySingletonReference;
            }
            // 在本init方法中被代理过了
            else if (!this.allowRawInjectionDespiteWrapping && // allowRawInjectionDespiteWrapping这个值默认是false
                     hasDependentBean(beanName)) {// hasDependentBean:若它有依赖的bean 那就需要继续校验了~~~(若没有依赖的 就放过它~)
                // 拿到它所依赖的Bean们~~~~ 下面会遍历一个一个的去看~~
                String[] dependentBeans = getDependentBeans(beanName);
                Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
                // 一个个检查它所以Bean
                // removeSingletonIfCreatedForTypeCheckOnly这个放见下面  在AbstractBeanFactory里面
                // 简单的说,它如果判断到该dependentBean并没有在创建中的了的情况下,那就把它从所有缓存中移除~~~  并且返回true
                // 否则(比如确实在创建中) 那就返回false 进入我们的if里面~  表示所谓的真正依赖
                //(解释:就是真的需要依赖它先实例化,才能实例化自己的依赖)
                for (String dependentBean : dependentBeans) {
                    if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
                        actualDependentBeans.add(dependentBean);
                    }
                }
                // 若存在真正依赖,那就报错(不要等到内存移除你才报错,那是非常不友好的) 
                // 这个异常是BeanCurrentlyInCreationException,报错日志也稍微留意一下,方便定位错误~~~~
                if (!actualDependentBeans.isEmpty()) {
                    throw new 。。。;
                }
            }
        }
    }

    // Register bean as disposable.
    try {
        registerDisposableBeanIfNecessary(beanName, bean, mbd);
    }catch (BeanDefinitionValidationException ex) {
        throw new BeanCreationException(
            mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
    }
    // 如论如何,要返回被代理的对象,而不是返回原始对象
    return exposedObject;
}
getSingleton
protected Object getSingleton(String beanName, boolean allowEarlyReference) {

    Object singletonObject = this.singletonObjects.get(beanName);
    if (singletonObject == null &&  isSingletonCurrentlyInCreation(beanName)) {
        synchronized (this.singletonObjects) {
            // 2 从earlySingletonObjects中获取
            singletonObject = this.earlySingletonObjects.get(beanName); 
            // 拿到了代理对象,不进入了
            if (singletonObject == null && allowEarlyReference) {
                ...;
            }
        }
    }
    // 返回提前代理好的对象
    return singletonObject;
}
放入单例池getSingleton

在doGetBean的第二个getSingleton中,在他里面,会进addSingleton(beanName, singletonObject);

public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
    Assert.notNull(beanName, "Bean name must not be null");
    synchronized (this.singletonObjects) {
        Object singletonObject = this.singletonObjects.get(beanName);
        if (singletonObject == null) {
            if (this.singletonsCurrentlyInDestruction) {
                throw new BeanCreationNotAllowedException(beanName,
                                                          "Singleton bean creation not allowed while singletons of this factory are in destruction " +
                                                          "(Do not request a bean from a BeanFactory in a destroy method implementation!)");
            }
            if (logger.isDebugEnabled()) {
                logger.debug("Creating shared instance of singleton bean '" + beanName + "'");
            }
            beforeSingletonCreation(beanName);
            boolean newSingleton = false;
            boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
            if (recordSuppressedExceptions) {
                this.suppressedExceptions = new LinkedHashSet<>();
            }
            try {
                // 创建,也就是我们文中大部分篇幅写的逻辑,里面是createBean
                singletonObject = singletonFactory.getObject();
                newSingleton = true;
            }
            catch (IllegalStateException ex) {
                // Has the singleton object implicitly appeared in the meantime ->
                // if yes, proceed with it since the exception indicates that state.
                singletonObject = this.singletonObjects.get(beanName);
                if (singletonObject == null) {
                    throw ex;
                }
            }
            catch (BeanCreationException ex) {
                if (recordSuppressedExceptions) {
                    for (Exception suppressedException : this.suppressedExceptions) {
                        ex.addRelatedCause(suppressedException);
                    }
                }
                throw ex;
            }
            finally {
                if (recordSuppressedExceptions) {
                    this.suppressedExceptions = null;
                }
                afterSingletonCreation(beanName);
            }
            if (newSingleton) {
                // 加入到单例池中,并且把别的里面的移除
                addSingleton(beanName, singletonObject);
            }
        }
        return singletonObject;
    }
}

getSingleton是在哪里被调用的呢?

doGetBean
//public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport implements ConfigurableBeanFactory {
protected <T> T doGetBean(
    final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly)throws BeansException {

    
    final String beanName = transformedBeanName(name);
    Object bean;

    Object sharedInstance = getSingleton(beanName);

    if (sharedInstance != null && args == null) {
        
        bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
    }
    else {
        if (isPrototypeCurrentlyInCreation(beanName)) {
            throw new BeanCurrentlyInCreationException(beanName);
        }

        // Check if bean definition exists in this factory.
        BeanFactory parentBeanFactory = getParentBeanFactory();
        if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
            // Not found -> check parent.
            String nameToLookup = originalBeanName(name);
            // 递归到beanFactory中寻找
            if (args != null) {
                // Delegation to parent with explicit args.
                return (T) parentBeanFactory.getBean(nameToLookup, args);
            }
            else {
                // No args -> delegate to standard getBean method.
                return parentBeanFactory.getBean(nameToLookup, requiredType);
            }
        }

        // 如果不是仅仅做类型检查则是创建bean,这里要做记录
        if (!typeCheckOnly) {
            markBeanAsCreated(beanName);
        }

        try {
            // 将存储XML配置文件的GernericBeanDefinition转换为RootBeanDefinition,如果指定beanName是子bean的话同时会合并父类的相关属性
            final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
            checkMergedBeanDefinition(mbd, beanName, args);

            // Guarantee initialization of beans that the current bean depends on.
            String[] dependsOn = mbd.getDependsOn();
            // 若存在依赖则需要递归实例化依赖的bean
            if (dependsOn != null) {
                for (String dep : dependsOn) {
                    if (isDependent(beanName, dep)) {throw ...;}
                    // 缓存依赖调用
                    registerDependentBean(dep, beanName);
                    getBean(dep);
                }
            }

            //------------doGetBean-4------------ //创建单例bean实例 
            if (mbd.isSingleton()) {// 判断当前bean是否单例
                
                sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() {//从这里进入getSingleton,并传入
                    @Override // getObject()里调用了createBean()
                    public Object getObject() throws BeansException {
                        try {
                            // 注:循环依赖的①会执行这里,②也会,但③不会。但是在createBean里①和②返回地方也不一样
                            return createBean(beanName, mbd, args);//createBean创建 // 好了我们可以取下面第二个getSingleton里看了
                        }
                        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);

            }else if (mbd.isPrototype()) {//多例的
                // It's a prototype -> create a new instance.
                Object prototypeInstance = null;
                try {
                    beforePrototypeCreation(beanName);
                    prototypeInstance = createBean(beanName, mbd, args);
                }
                finally {
                    afterPrototypeCreation(beanName);
                }
                bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
            }else { //指定的scope上实例化bean
                String scopeName = mbd.getScope();
                final Scope scope = this.scopes.get(scopeName);
                if (scope == null) {throw... ;}
                try {
                    Object scopedInstance = scope.get(beanName, new ObjectFactory<Object>() {
                        @Override
                        public Object getObject() throws BeansException {
                            beforePrototypeCreation(beanName);
                            try {
                                return createBean(beanName, mbd, args);
                            }
                            finally {
                                afterPrototypeCreation(beanName);
                            }
                        }
                    });
                    bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
                }
                catch (IllegalStateException ex) {throw ...;}
            }
        }
        catch (BeansException ex) {
            cleanupAfterBeanCreationFailure(beanName);
            throw ex;
        }
    }

    // 检查需要的类型是否符合bean的实际类型
    // Check if required type matches the type of the actual bean instance.
    if (requiredType != null && bean != null && !requiredType.isInstance(bean)) {
        try {
            return getTypeConverter().convertIfNecessary(bean, requiredType);
        }
        catch (TypeMismatchException ex) {
            throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
        }
    }
    return (T) bean;//finish阶段直接return的有
}

总结

SmartInstantiationAwareBeanPostProcessor

这个类有点意思,他是一个后置处理器,并且里面有个方法是getEarlyBeanReference(),他就是说这个后置处理器可以提前提供代理

public Object getEarlyBeanReference(Object bean, String beanName) {
    Object cacheKey = getCacheKey(bean.getClass(), beanName);
    this.earlyProxyReferences.put(cacheKey, bean);
    return wrapIfNecessary(bean, beanName, cacheKey);
}

三级缓存流程

A实例化的时候把bean工厂提前准备好,这样发生循环依赖就能用了

B填充A属性的时候发现在singletonsCurrentlyInCreation中,说明出现了循环依赖,A就去三级缓存中拿到bean工厂提前代理好,然后放到earlySingletonObjects中。全部执行完后,相当于getBean最后一步再放到单例池中

关键在于wrapIfNecessary()这个方法

至此,循环依赖结束,而代理的细节还没说,下篇解释吧

【Spring源码:循环依赖】一文弄懂Spring循环依赖 1. 什么是循坏依赖 很简单,其实就是互相依赖对方,比如,有一个A对象依赖了B对象,B对象又依赖了A对象。 // A依赖了B public class A{ private B b; } // B依赖了A public class B{ private A a; } 但是,在我们普通的java开发中,循坏依赖会出现问题吗? 如果不考虑Spring,循环依赖并不是问题,因为对象之间相互依赖注入是很正常的事情。 比如: 这样,A,B就互相依赖上了。 但是,在Spring 阅读详情

相关推荐

Spring5.0源码学习系列之浅谈循环依赖问题(八)

所谓的循环依赖就是指两个及以上的类互相调用依赖,形成闭环,Spring框架检测到这种场景会抛 BeanCurrentlyInCreationException,提前暴露对象的方法

Nicky's blog 3087

Spring框架(四) 三级缓存与循环依赖

1.循环依赖 首先我们需要明白什么是循环依赖 , 打个比方 , 就是说A对象在创建的过程中 , 需要依赖注入B对象 , 但是B对象没有 , 就需要去创建 , 而在创建B对象的过程中又需要注入A对象 , A对象此时还在创建中,所以就构成了一个死循环 , A,B相互依赖 这样的关系被成为循环依赖(当然 , 可能还会有其他的情况),下面我们就来看看Spring是如何让解决循环依赖的 2.一二三级缓存 三个缓存对应着三个不同的Map 一级:singletonObjects 这个缓存也就是单例池 , 它存放

刘跃辉的博客 10万+

spring循环依赖源码分析

绪论 在使用spring或者springboot项目开发中,经常通过注入的方式完成一个bean对另一个bean的引用,比如classA中药注入B的bean,写法如下 @Autowired private B b 而B中要注入A的话就是下面的写法了 @Autowired private A a 用法非常简单,一目了然,用习惯了就成自然了,觉得就是那么回事,但小编最近读了点儿spring源码,就想...

congge 3万+

Spring源码学习(九)--循环依赖

什么是循环依赖? 很简单,就是A对象依赖了B对象,B对象依赖了A对象。 比如: // A依赖了B class A{ public B b; } // B依赖了A class B{ public A a; } 那么循环依赖是个问题吗? 如果不考虑Spring,循环依赖并不是问题,因为对象之间相互依赖是很正常的事情。 比如 A a = new A(); B b = new B(); a.b = b; b.a = a; 这样,A,B就依赖上了。 但是,在Spring中循.

学习笔记 1775

利用ENVI处理TIF文件,把多个tif整合到一个完整的tif,例如2003-2011年的tif整合到一个tif上。

利用ENVI处理TIF文件,把多个tif整合到一个完整的tif,例如2003-2011年的tif整合到一个tif上。

unique_sir的博客 1万+

UE4-(IK)实现人物脚贴合地面解决斜坡上脚无旋转无法贴合地面问题

在斜面上脚陷入模型中,需要设置旋转值对脚的骨骼进行一个旋转。 解决思路:在射线检测中可以获取到检测点的法线方向,根据法线方向来计算出脚应该向哪个方向进行适当的旋转,在斜坡上,人物脚需要旋转的轴为x轴和y轴以便来贴合地面,z轴方向的旋转是不需要进行修改的。 如图所示,我们需要求得水平面与斜坡的夹角用来得出人物在x轴上的脚旋转量,在蓝图中提供反正切函数,反正切 = 锐角的邻边/对边 所以 反正切值(脚x轴值(roll)) = 法线Y轴值/法线Z轴 值。 现在将上图的人物想象成面向屏幕,脚需...

Stone的博客 3315

Spring之循环依赖底层源码解析(二)

Spring之循环依赖底层源码解析 三级缓存 解决循环依赖思路分析 总结 三级缓存总结 反向分析singletonFactories 三级缓存 三级缓存是通用的叫法 一级缓存: singletonObjects singletonObjects中缓存的是已经经历了完整生命周期的Bean对象 二级缓存: earlySingletonObjects earlySingletonObjects比singletonObjects多了一个early,表示缓存的是早期的Bean对象

枫度柚子 1609

手把手教你用VCS+Verdi在Linux下仿真蜂鸟E203 RISC-V核(附波形调试技巧)

本文详细介绍了在Linux环境下使用VCS和Verdi工具链对蜂鸟E203 RISC-V核进行仿真验证的完整流程。从环境配置、工程结构解析到VCS编译优化和Verdi波形分析技巧,提供了实战性强的调试方法和性能优化策略,帮助工程师高效完成数字IC验证工作。

weixin_42531163的博客 415

Spring循环依赖原理及底层源码解析

文章目录一、什么是循环依赖二、Bean的生命周期三、三级缓存四、解决循环依赖思路分析1、如何打破循环依赖2、singletonFactories3、earlySingletonObjects五、总结反向分析一下singletonFactories 一、什么是循环依赖 很简单,就是A对象依赖了B对象,B对象依赖了A对象。 比如: // A依赖了B class A{ public B b; } // B依赖了A class B{ public A a; } 那么循环依赖是个问题吗? 如果不考虑Sprin

沮丧的南瓜 1760

机器学习-深嵌交叉验证(Nested Cross-Validation)

Section I: Code and Analyses 第一部分:代码 from sklearn import datasets from sklearn.model_selection import train_test_split from sklearn.preprocessing import StandardScaler from sklearn.svm import SVC from...

Santorinisu Blogs 2714

西瓜书第二章——模型评估与选择(十折交叉验证/查准查全F1)

第二章——模型评估与选择

xsddys的博客 951

深入剖析Spring框架:循环依赖的解决机制

如果当前Bean没有出现循环依赖,那么这个Lambda表达式没用,当前bean按照自己的生命周期正常执行,执行完后直接把当前bean放入singletonObjects中,如果当前bean在依赖注入时发现出现了循环依赖(当前正在创建的bean被其他bean依赖了),则从三级缓存中拿到Lambda表达式,并执行Lambda表达式得到一个对象,并把得到的对象放入二级缓存((如果当前Bean需要AOP,那么执行lambda表达式,得到就是对应的代理对象,如果无需AOP,则直接得到一个原始对象))。

木卯的专栏 1061

解决eNSP安装WinPcap版本冲突的完整指南

网络数据包捕获工具WinPcap是网络仿真环境的基础组件,其版本兼容性直接影响eNSP等网络模拟器的正常运行。当系统已安装新版WinPcap时,eNSP内置的旧版安装程序会因版本校验机制触发报错。通过彻底卸载现有驱动、安装特定版本WinPcap 4.1.2,并验证注册表和服务状态,可解决版本冲突问题。对于需要同时使用新版驱动的场景,可采用虚拟机隔离或Npcap兼容模式。该方案适用于Windows 10/11系统环境,涉及驱动签名、虚拟网卡等典型网络工程问题。

weixin_32612263的博客 336

Spring 源码(八)循环依赖源码解析

循环依赖是指两个或者多个Bean之前相互持有对方。在Spring中循环依赖一般有三种方式: 构造函数循环依赖 setter方法循环依赖 prototype 范围的依赖处理 构造函数循环依赖 在Spring中构造函数循环依赖是无法解决的,因为构造函数依赖其实是方法间循环调用的一种,会发生死循环。但是在Spring中会直接抛出BeanCurrentlyInCreationException异常。源...

xiaolyuh的专栏 635

OceanBase数据库:与MySQL和Oracle的函数差异分析

OceanBase数据库兼容性解析:MySQL与Oracle模式深度比较 摘要:OceanBase通过独特的双模式架构,实现了对MySQL和Oracle的高度兼容。文章首先分析了OceanBase的兼容性架构,包括SQL解析层、优化器层和执行引擎层的差异化设计。随后对比了两种模式在数据类型、SQL语法、函数支持等方面的兼容性差异,其中MySQL模式兼容5.7版本大部分功能,Oracle模式则支持155个内置函数和PL/SQL特性。最后提出了模式选择的六大考量因素,包括现有系统基础、功能需求和迁移成本等,为数

本博客聚焦 YOLOv11 全流程落地,涵盖架构优化、数据集处理、训练技巧与多场景部署,兼及国产数据库、Java 开发与 AI 模型应用,内容兼顾理论与工程实践,为开发者提供系统干货,助力高效提升技术能力。 1226

手把手教你学AUTOSAR(13.1)--基于 AUTOSAR 的开发实战实例(一)

通过上述几个基于 AUTOSAR 的开发实战实例,你可以全面了解如何从需求分析、系统设计、软件开发、集成测试到部署和验证等多个环节进行 AUTOSAR 系统的开发。这些实例不仅涵盖了不同的应用场景,还提供了具体的代码实现和技术细节,帮助你更好地应用 AUTOSAR 标准。

MHD0815的博客 1195

spring 5.0.x源码学习系列八: 实例化bean之使用构造方法创建bean、自动装配与循环依赖

前言 上篇博客spring 5.0.x源码学习系列七: 后置处理器ConfigurationClassPostProcessor之BeanFactoryPostProcessor身份主要介绍了ConfigurationClassPostProcessor的BeanFactoryPostProcessor身份。接下来,将进入spring最核心的bean实例化过程总结。 一、 ...

avengerEug的博客 503

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

Spring源码剖析-Spring如何处理循环依赖

前言 你是不是被这个骚气的标题吸引进来的,_ 喜欢我的文章的话就给个好评吧,你的肯定是我坚持写作最大的动力,来吧兄弟们,给我一点动力 Spring如何处理循环依赖?这是最近较为频繁被问到的一个面试题,在前面Bean实例化流程中,对属性注入一文多多少少对循环依赖有过介绍,这篇文章详细讲一下Spring中的循环依赖的处理方案。 什么是循环依赖 依赖指的是Bean与Bean之间的依赖关系,循环依赖指的是两个或者多个Bean相互依赖,如: 构造器循环依赖 代码示例: public class BeanA {

墨家巨子@俏如来 6185

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

Spring源码最难问题《当Spring AOP遇上循环依赖》

4.AOP中的循环依赖 在看自动代理源码的过程中,突然注意到SmartInstantiationAwareBeanPostProcessor接口中的getEarlyBeanReference方法,它是Spring处理循环依赖时返回**未创建完(只实例化未做依赖注入)**Bean的扩展。关于循环依赖可以去Bean的循环依赖一章去详细了解,这里只做简单的说明。 有两个单例Bean,A和B,A中引用了B...

bugpool的博客 1万+

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

Spring源码解析(五):循环依赖

简单点说,就是A依赖了B,B依赖的A如果不处理,那么A创建时候需要属性填充B此时B还没有创建,那么去创建B,又需要属性填充A以此形成了死循环A依赖BB依赖A,自然排序,所以先实例化AgetBean(a),先从缓存中获取,没有,则需要去创建实例化A,创建一个对象工厂,可以通过getObje返回刚实例化的A对象,将对象工厂放入三级缓存A属性填充,需要给A中的b属性赋值,则需要getBean(b),先从缓存中获取,没有,则需要去创建。

从基础到源码解析的学习记录 975

Spring源码分析十:Spring中的循环依赖深度解析

Spring源码分析十:Spring中的循环依赖深度解析

我从不打没有准备的仗! 1万+

Spring深度学习:循环依赖及源码解析

本文小豪将带大家深度学习Spring循环依赖相关知识,包括循环依赖的解决方案及Spring处理循环依赖的底层源码,学习过程中不仅仅是了解Spring处理循环依赖的设计,更重要的是学会理解框架的底层逻辑,从而提升我们的思维能力。

Code豪客 1877

spring源码分析之循环依赖以及解决方案

本篇博文分几个点:什么是循环引用、循环引用的类型、spring对循环引用的解决、通过一个例子列举处理了spring中循环引用的问题,并通过对spring部分源码的分析简明扼要的解释了spring对于循环引用的结局。希望能对大家工作中遇到的这类问题有所帮助。

liushangzaibeijing的博客 6万+

[spring源码]spring循环依赖

[spring源码]spring循环依赖

CUITLY_的博客 990

Spring源码解析-Spring 循环依赖

⼀个或多个对象之间存在直接或间接的依赖关系,这种依赖关系构成⼀个环形调⽤,有下⾯ 3 种⽅式。我们看⼀个简单的 Demo,对标“情况 2”。@Service@Autowired@Service@Autowired这是⼀个经典的循环依赖,它能正常运⾏,后⾯我们会通过源码的⻆度,解读整体的执⾏流程。我们再回顾⼀下 3 级缓存的作⽤:⼀级缓存:为“Spring 的单例属性”⽽⽣,就是个单例池,⽤来存放已经初始化完成的单例 Bean;

qq_66627105的博客 1092

Spring源码之循环依赖

在Spring中,通过引入singletonsCurrentlyInCreation、singletonObjects、earlySingletonObjects、singletonFactories、earlyProxyReferences缓存,解决普通/代理对象的循环依赖问题。无法解决的循环依赖情况有:①构造方法注入;②依赖与被依赖的Bean均为多例Bean。

qq_26783889的博客 793
上一篇: 【spring源码】七、后置处理器BeanPostProcessor
下一篇: 【spring源码】九、spring动态代理的创建
hancoder
博客等级 码龄9年 4135粉丝 167原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值