Spring Bean生命周期和循环依赖

Spring

1. Spring 容器的加载过程

请添加图片描述
完整脑图下载,加方法注释
在这里插入图片描述

Refresh

  1. this.prepareRefresh();

    准备容器,设置容器的基本属性值

  2. this.obtainFreshBeanFactory();

    创建一个BeanFactory工厂,读取配置文件中的BeanDefinition

  3. this.prepareBeanFactory(beanFactory);

上一个步骤只是简单的得到一个BeanFactory工厂,这一步是对工厂进行属性赋值

  1. this.postProcessBeanFactory(beanFactory);

空方法,留给子类进行拓展操作

  1. this.invokeBeanFactoryPostProcessors(beanFactory);

调用BeanFactory处理器,BeanFactoryPostProcessor

  1. this.registerBeanPostProcessors(beanFactory);

准备实例化阶段需要的BeanPostProcessors

  1. this.initMessageSource();

为上下文初始化message源,即不同语言的消息体,国际化处理

  1. this.initApplicationEventMulticaster();

初始化事件监听多路广播器。(通过多路广播器监听Bean对象在什么阶段去做什么样的事情)

  1. this.onRefresh();

留给子类初始化其他Bean对象。

  1. this.registerListeners();

    注册监听。在所有注册的bean中查找listener bean,注册到消息广播器中

  2. this.finishBeanFactoryInitialization(beanFactory);

    初始化对象。getBean==>doGetBean==>getSingleton/createBean==>doCreateBean==>createBeanInstrance//addSingletonFactory/populateBean/initialzeBean

  3. this.finishRefresh();

> 在所有注册的`bean`中查找`listener bean`,注册到消息广播器中

在这里插入图片描述

对应,初始化阶段,先执行 aware,然后再执行beanPostProcessors

2. Spring Bean 的生命周期

请添加图片描述

初始化Bean的先后顺序为

BeanPostProcessor的postProcessBeforeInitialization方法
类中添加了注解@PostConstruct 的方法
InitializingBean的afterPropertiesSet方法
bean的指定的初始化方法: init-method
BeanPostProcessor的postProcessAftrInitialization方法

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> T doGetBean(String name, @Nullable Class<T> 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<String,ObjectFactory>不为空时
    //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()(将三级缓存中的B对象移除,放入一级缓存中);

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> {

	/**
	 * Return an instance (possibly shared or independent)
	 * of the object managed by this factory.
	 * @return the resulting instance
	 * @throws BeansException in case of creation errors
	 */
	T getObject() throws BeansException;

}


public class DefaultSingletonBeanRegistry{
    //缓存对象:一级缓存
    private final Map<String, Object> singletonObjects = new ConcurrentHashMap(256);
    //缓存对象:三级缓存
    private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap(16);
    //缓存对象:二级缓存
    private final Map<String, Object> 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<String,ObjectFactory>不为空时
                            //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<String> 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 Object resolveValueIfNecessary(Object argName, @Nullable Object value) {
     *      return this.resolveReference(argName, ref);
     * }
     * 
     *   private Object resolveReference(Object argName, RuntimeBeanReference ref) {
     *         .....
     *					  //从工厂中获取Bean对象
     *                     bean = this.beanFactory.getBean(resolvedName);
     *        .......
     *     }
     *    public Object getBean(String name) throws BeansException {
     *			//再次调用doGetBean方法。递归循环调用
     *		   return this.doGetBean(name, (Class)null, (Object[])null, false);
     *	  }
     */
    }

}


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

在这里插入图片描述

三级缓存解决循环依赖问题的关键是什么?为什么通过提前暴露对象能解决问题?

通过实例化和初始化分开操作,在中间过程中给其他对象赋值的时候,并不是一个完整对象,而是把半成品对象赋值给了其他对象。

如果只使用一级缓存能不能解决问题?

不能,在整个处理过程中,缓存中放的是半成品和成品对象,如果只有一级缓存,那么成品和半成品都会放到一级缓存中,有可能在获取过程中获取到半成品对象,此时半成品对象是无法使用的。因此要把半成品和成品的存放空间区分开。

只使用二级缓存行不行,为什么需要三级缓存?

如果能保证所有的Bean对象都不调用getEarlyBeanReference此方式,使用二级缓存可以吗?

是的,如果保证都不调用就可以只使用二级缓存。

使用三级缓存的本质就在于解决aop代理问题

protected Object getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean) {
        Object exposedObject = bean;
        if (!mbd.isSynthetic() && this.hasInstantiationAwareBeanPostProcessors()) {
            Iterator var5 = this.getBeanPostProcessors().iterator();

            while(var5.hasNext()) {
                BeanPostProcessor bp = (BeanPostProcessor)var5.next();
                if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
                    SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor)bp;
                    //代码A
                    exposedObject = ibp.getEarlyBeanReference(exposedObject, beanName);
                }
            }
        }

        return exposedObject;
}
//代码A处方法的实现类就有AbstractAutoProxyCreateor。ibp.getEarlyBeanReference方法就是获取代理对象。

为什么三级缓存就可以解决这个问题?

当一个对象需要被代理的时候,在整个创建过程中是包含两个对象,一个普通对象,一个代理对象。Bean默认都是单例,那么在整个生命周期处理的环节中, 一个BeanName是不能对应两个对象的。所以在处理的过程中,需要判断动态的进行代理。getEarlyBeanReference方法中就是动态的进行代理。

参考文档:

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

王叮咚

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值