栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Spring Bean生命周期和循环依赖

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Spring Bean生命周期和循环依赖

Spring 1. Spring 容器的加载过程


完整脑图下载,加方法注释

2. Spring Bean 的生命周期

3. Spring的循环依赖 3.1 什么是Spring的循环依赖

问题描述:

Spring中存在两个类(类A和类B),A对象中有B对象,B对象中有A对象;

public class A{
    private B b;
}
public class B{
    private A a;
}

Spring容器在初始化时,如何解决这两个Bean的循环依赖问题?

3.2 Spring 中Bean的创建流程

Spring 中 Bean 的创建是分为 实例化和初始化两个步骤的(也只有这样分为两个步骤,才能解决循环依赖的问题)

实例化:仅仅只是完成对象堆空间的开辟,不完成对象属性的赋值
初始化:对对象的属性完成赋值操作

接下来,我们用图解来表示出循环依赖A,B对象的创建过程

3.3 核心步骤&核心代码

在我们对上面图片中的对象创建过程进行代码讲解时,我们需要先熟练掌握下面的几段代码块

step1: Spring容器进行对象A的实例化

step2: 实例化的过程中,先会去判断容器中是否有bean对象了(getSingleton():依次从一级缓存到二级缓存到三级缓冲中获取是否存在bean对象);

step3: 此时容器中没有Bean对象的缓存,所以需要去new一个新的A对象;

this.getSingleton(beanName, () -> {return this.createBean(beanName, mbd, args);}

step2: 实例化完A对象后instanceWrapper.getWrappedInstance();,将数据(半成品A)放入三级缓存中

半成品:仅仅完成了实例化,未完成初始化

this.addSingletonFactory(beanName, () -> {
                return this.getEarlyBeanReference(beanName, mbd, bean);
});
protected void addSingletonFactory(String beanName, ObjectFactory singletonFactory) {
        Assert.notNull(singletonFactory, "Singleton factory must not be null");
        synchronized(this.singletonObjects) {
            if (!this.singletonObjects.containsKey(beanName)) {
                //放入三级缓存 key:beanName为A,value:lambda表达式
                this.singletonFactories.put(beanName, singletonFactory);
                //移除二级缓存 beanName为A
                this.earlySingletonObjects.remove(beanName);
                this.registeredSingletons.add(beanName);
            }

        }
    }

step3: 三级缓存中放入对象后,进行充A中的B属性this.populateBean(beanName, mbd, instanceWrapper);的操作

protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
    ......
    if (pvs != null) {
                this.applyPropertyValues(beanName, mbd, bw, (PropertyValues)pvs);
    }     
}
protected void applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs) {
    ....
    Object resolvedValue = valueResolver.resolveValueIfNecessary(pv, originalValue);
    .....
}
public Object resolveValueIfNecessary(Object argName, @Nullable Object value) {
	....
    return this.resolveReference(argName, ref);
    ....
}
private Object resolveReference(Object argName, RuntimeBeanReference ref) {
	....
    bean = this.beanFactory.getBean(resolvedName);
    ...
}

step4: 尝试去获取B对象的缓存,此时容器中没有Bean对象的缓存,所以需要去new一个新的B对象;

public Object getBean(String name) throws BeansException {
    return this.doGetBean(name, (Class)null, (Object[])null, false);
}
protected  T doGetBean(String name, @Nullable Class requiredType, @Nullable Object[] args, boolean typeCheckOnly) throws BeansException {
	....
	Object sharedInstance = this.getSingleton(beanName);
	...
}

step5: 实例化完B对象后instanceWrapper.getWrappedInstance();,将数据(半成品B)放入三级缓存中;

step6: 三级缓存中放入对象后,填充B中的A属性this.populateBean(beanName, mbd, instanceWrapper);

step7: 同样,尝试从缓存中获取A对象来填充B中A的属性,因为之前A对象已经放入三级缓存中了,所以可以直接从缓存中取出A对象的半成品赋值给B对象;

step8: 当成功从三级缓存中获取到A对象时,会将A对象方法二级缓存中,并且从三级缓存中移除A

protected Object getSingleton(String beanName, boolean allowEarlyReference) {
	....
    //从三级缓存中获取对象
        ObjectFactory singletonFactory = (ObjectFactory)this.singletonFactories.get(beanName);
    //当三级缓存中的对象Map不为空时
    //ObjectFactory为函数式接口
    if (singletonFactory != null) {
        //调用Lambda表达式中的方法
        singletonObject = singletonFactory.getObject();
        //将Key,value放入二级缓存中
        this.earlySingletonObjects.put(beanName, singletonObject);
        this.singletonFactories.remove(beanName);
    }
    return singletonObject;
}

step9: B对象中的A对象的赋值完成,此时B对象已经是一个完成品(已实例化,已初始化,初始化中的A对象为半成品);(此时B对象已完成,所以我们要继续step3的操作,进行A对象中B对象的赋值操作)。但是在继续step3操作之前,会先调用addSingleton();

protected void addSingleton(String beanName, Object singletonObject) {
    synchronized(this.singletonObjects) {
    	//放入一级缓存beanName: B value:完成品的B对象
        this.singletonObjects.put(beanName, singletonObject);
        //移除二级、三级缓存
        this.singletonFactories.remove(beanName);
        this.earlySingletonObjects.remove(beanName);
        this.registeredSingletons.add(beanName);
    }
}

step10: B对象已完成创建且赋值,A中B属性的赋值,只需要将返回的对象,赋值给B属性。即完成了循环依赖;

step11: A对象完成赋值操作后,创建操作完成,调用addSingleton();,将完成品的A对象放入一级缓存中,移除二三级缓存的A对象;

step12:此时Spring容器中的缓存里,已经存储有A,B对象的完成品,且完成了循环依赖,上面介绍了A对象创建过程中Spring容器的流程(A对象创建的过程中顺便完成了B对象的创建,并且放到了缓存中)。我们的目的是创建A,B对象,接下来,B对象的创建,Spring尝试从缓存中获取B对象。此时我们发现,B对象的缓存已经存在于Spring容器中,直接返回B对象即可;

核心代码

@FunctionalInterface
public interface ObjectFactory {

	
	T getObject() throws BeansException;

}


public class DefaultSingletonBeanRegistry{
    //缓存对象:一级缓存
    private final Map singletonObjects = new ConcurrentHashMap(256);
    //缓存对象:三级缓存
    private final Map> singletonFactories = new HashMap(16);
    //缓存对象:二级缓存
    private final Map earlySingletonObjects = new ConcurrentHashMap(16);
    
    public Object getSingleton(String beanName) {
        return this.getSingleton(beanName, true);
    }
    
    protected Object getSingleton(String beanName, boolean allowEarlyReference) {
        //尝试从一级缓存中获取对象
        Object singletonObject = this.singletonObjects.get(beanName);
        //判断一级缓存中对象是否为空 且 为正创建中的对象
        if (singletonObject == null && this.isSingletonCurrentlyInCreation(beanName)) {
            //尝试从二级缓存中获取对象
            singletonObject = this.earlySingletonObjects.get(beanName);
            //判断二级缓存中对象是否为空 
            if (singletonObject == null && allowEarlyReference) {
                synchronized(this.singletonObjects) {
                    //尝试从一级缓存中获取对象
                    singletonObject = this.singletonObjects.get(beanName);
                    //判断一级缓存中对象是否为空
                    if (singletonObject == null) {
                        //尝试从二级缓存中获取对象
                        singletonObject = this.earlySingletonObjects.get(beanName);
                        if (singletonObject == null) {
                            //从三级缓存中获取对象
                            ObjectFactory singletonFactory = (ObjectFactory)this.singletonFactories.get(beanName);
                            //当三级缓存中的对象Map不为空时
                            //ObjectFactory为函数式接口
                            if (singletonFactory != null) {
                                //调用Lambda表达式中的方法
                                singletonObject = singletonFactory.getObject();
                                //将Key,value放入二级缓存中
                                this.earlySingletonObjects.put(beanName, singletonObject);
                                this.singletonFactories.remove(beanName);
                            }
                        }
                    }
                }
            }
        }

        return 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 (this.logger.isDebugEnabled()) {
                    this.logger.debug("Creating shared instance of singleton bean '" + beanName + "'");
                }

                this.beforeSingletonCreation(beanName);
                boolean newSingleton = false;
                boolean recordSuppressedExceptions = this.suppressedExceptions == null;
                if (recordSuppressedExceptions) {
                    this.suppressedExceptions = new LinkedHashSet();
                }

                try {
                    //调用lambda表达式
                    singletonObject = singletonFactory.getObject();
                    newSingleton = true;
                } catch (IllegalStateException var16) {
                    singletonObject = this.singletonObjects.get(beanName);
                    if (singletonObject == null) {
                        throw var16;
                    }
                } catch (BeanCreationException var17) {
                    BeanCreationException ex = var17;
                    if (recordSuppressedExceptions) {
                        Iterator var8 = this.suppressedExceptions.iterator();

                        while(var8.hasNext()) {
                            Exception suppressedException = (Exception)var8.next();
                            ex.addRelatedCause(suppressedException);
                        }
                    }

                    throw ex;
                } finally {
                    if (recordSuppressedExceptions) {
                        this.suppressedExceptions = null;
                    }

                    this.afterSingletonCreation(beanName);
                }

                if (newSingleton) {
                    this.addSingleton(beanName, singletonObject);
                }
            }

            return singletonObject;
        }
    }
}

    


public class AbstractAutowireCapableBeanFactory{
    
    protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException {
        if (this.logger.isTraceEnabled()) {
            this.logger.trace("Creating instance of bean '" + beanName + "'");
        }

        RootBeanDefinition mbdToUse = mbd;
        Class resolvedClass = this.resolveBeanClass(mbd, beanName, new Class[0]);
        if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
            mbdToUse = new RootBeanDefinition(mbd);
            mbdToUse.setBeanClass(resolvedClass);
        }

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

        Object beanInstance;
        try {
            beanInstance = this.resolveBeforeInstantiation(beanName, mbdToUse);
            if (beanInstance != null) {
                return beanInstance;
            }
        } catch (Throwable var10) {
            throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName, "BeanPostProcessor before instantiation of bean failed", var10);
        }

        try {
            //调用createBean方法
            beanInstance = this.doCreateBean(beanName, mbdToUse, args);
            if (this.logger.isTraceEnabled()) {
                this.logger.trace("Finished creating instance of bean '" + beanName + "'");
            }

            return beanInstance;
        } catch (ImplicitlyAppearedSingletonException | BeanCreationException var7) {
            throw var7;
        } catch (Throwable var8) {
            throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", var8);
        }
    }
    
        protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException {
        BeanWrapper instanceWrapper = null;
        if (mbd.isSingleton()) {
            instanceWrapper = (BeanWrapper)this.factoryBeanInstanceCache.remove(beanName);
        }

        if (instanceWrapper == null) {
            instanceWrapper = this.createBeanInstance(beanName, mbd, args);
        }
		//实例化Bean对象
        Object bean = instanceWrapper.getWrappedInstance();
        Class beanType = instanceWrapper.getWrappedClass();
        if (beanType != NullBean.class) {
            mbd.resolvedTargetType = beanType;
        }

        synchronized(mbd.postProcessingLock) {
            if (!mbd.postProcessed) {
                try {
                    this.applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
                } catch (Throwable var17) {
                    throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Post-processing of merged bean definition failed", var17);
                }

                mbd.postProcessed = true;
            }
        }

        boolean earlySingletonExposure = mbd.isSingleton() && this.allowCircularReferences && this.isSingletonCurrentlyInCreation(beanName);
        if (earlySingletonExposure) {
            if (this.logger.isTraceEnabled()) {
                this.logger.trace("Eagerly caching bean '" + beanName + "' to allow for resolving potential circular references");
            }
			//调用addSingletonFactory方法,传入形参 bean和ObjectFactory的实现类
            this.addSingletonFactory(beanName, () -> {
                return this.getEarlyBeanReference(beanName, mbd, bean);
            });
        }

        Object exposedObject = bean;

        try {
            //填充属性(填充A对象中的B对象属性或者B对象中填充A对象的属性)
            this.populateBean(beanName, mbd, instanceWrapper);
            exposedObject = this.initializeBean(beanName, exposedObject, mbd);
        } catch (Throwable var18) {
            if (var18 instanceof BeanCreationException && beanName.equals(((BeanCreationException)var18).getBeanName())) {
                throw (BeanCreationException)var18;
            }

            throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Initialization of bean failed", var18);
        }

        if (earlySingletonExposure) {
            Object earlySingletonReference = this.getSingleton(beanName, false);
            if (earlySingletonReference != null) {
                if (exposedObject == bean) {
                    exposedObject = earlySingletonReference;
                } else if (!this.allowRawInjectionDespiteWrapping && this.hasDependentBean(beanName)) {
                    String[] dependentBeans = this.getDependentBeans(beanName);
                    Set actualDependentBeans = new LinkedHashSet(dependentBeans.length);
                    String[] var12 = dependentBeans;
                    int var13 = dependentBeans.length;

                    for(int var14 = 0; var14 < var13; ++var14) {
                        String dependentBean = var12[var14];
                        if (!this.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.");
                    }
                }
            }
        }

        try {
            this.registerDisposableBeanIfNecessary(beanName, bean, mbd);
            return exposedObject;
        } catch (BeanDefinitionValidationException var16) {
            throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Invalid destruction signature", var16);
        }
    }
    

    
        protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
        ......
            if (pvs != null) {
                this.applyPropertyValues(beanName, mbd, bw, (PropertyValues)pvs);
            }

        }

    protected void applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs) {
        .....
                        Object resolvedValue = valueResolver.resolveValueIfNecessary(pv, originalValue);
           .....
    
    }

}


public class DefaultSingletonBeanRegistry{
    
        protected void addSingletonFactory(String beanName, ObjectFactory singletonFactory) {
        Assert.notNull(singletonFactory, "Singleton factory must not be null");
        synchronized(this.singletonObjects) {
            //判断一级缓存中是否含有key为beanName的数据
            if (!this.singletonObjects.containsKey(beanName)) {
                //key:lambda表达式放入三级缓存
                this.singletonFactories.put(beanName, singletonFactory);
                //二级缓存中移除key
                this.earlySingletonObjects.remove(beanName);
                this.registeredSingletons.add(beanName);
            }
        }
    }
}

参考文档:

B站:Spring源码深度解析31精讲,阿里P8架构师讲解的太牛了!

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/848309.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号