循环依赖-三级缓存

循环依赖概念

spring容器帮助我们管理对象,简称Bean,大多数情况下我们都是使用单例bean,也就是从容器中重复利用这个Bean,在生成Bean的过程中需要为某些成员变量赋值,比如现在有类A和B被spring容器管理,A类中有个依赖容器成员变量B,B类中有个依赖容器的成员变量A。

@Component
public class A  {@Autowiredprivate B b;
}@Component
public class B{@Autowiredprivate A a;
}

在spring容器生成类A的Bean时,为其进行属性填充,发现需要容器中的一个B类型的Bean,但此时容器中还没有B类型的Bean,此时会去先生成B类的Bean再给A进行属性填充。

同理,spring容器生成类B的Bean时,为其进行属性填充,发现需要容器中的一个A类型的Bean,但此时容器中还没有A类型的Bean,此时会去先生成A类的Bean再给B进行属性填充。

如果按照这样的逻辑来管理Bean的话,那就会陷入一个死循环,spring为了解决循环依赖,引入了三级缓存处理。整个处理流程也就是《refresh之finishBeanFactoryInitialization(beanFactory)》

下面将介绍源码处理过程中的一些基本概念

  1. 一级缓存存放单例Bean:Map<beanName,Bean> SingletonObjects
  2. 二级缓存存放的是未走完Bean的生命周期的不完整初始Bean或者提前进行AOP的Bean ,它是利用三级缓存来生产的:Map<beanName,Bean> EaarlySingletonObjects
  3. 三级缓存存放的是一个ObjectFactory对象,添加的时机在实例化后,属性填充前,给出了一个lamda表达式,调用它的getObject()方法就是调用了getEarlyBeanRederence()方法:Map<beanName,ObjectFactory> SingletonFactories
  4. 第一个重载的getSingleton()
	protected Object getSingleton(String beanName, boolean allowEarlyReference) {
//		一级缓存单例池拿Object singletonObject = this.singletonObjects.get(beanName);//如果一级缓存没拿到并且是否正在创建,第一次A还没有开始创建,false,singletonsCurrentlyInCreation:是否正在创建if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
//			进来了说明存在循环依赖synchronized (this.singletonObjects) {
//				从二级缓存获取singletonObject = this.earlySingletonObjects.get(beanName);//二级缓存也没拿到,尝试用三级缓存if (singletonObject == null && allowEarlyReference) {ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);if (singletonFactory != null) {//也就是调用getEarlyBeanRederence()方法singletonObject = singletonFactory.getObject();//放入二级缓存,删除三级缓存this.earlySingletonObjects.put(beanName, singletonObject);this.singletonFactories.remove(beanName);}}}}return singletonObject;}
  1. 第二个重载的getSingleton()
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {synchronized (this.singletonObjects) {
//			先从一级缓存拿Object singletonObject = this.singletonObjects.get(beanName);if (singletonObject == null) {//拿不到,准备生产,设置标志位,singletonsCurrentlyInCreation:正在创建的bean,inCreationCheckExclusions:用来抛出异常,即构造函数循环依赖无法解决beforeSingletonCreation(beanName);boolean newSingleton = false;boolean recordSuppressedExceptions = (this.suppressedExceptions == null);if (recordSuppressedExceptions) {this.suppressedExceptions = new LinkedHashSet<>();}try {
//					这里调用的就是那个singletonFactory的lambda表达式的createBean方法去创建BeansingletonObject = singletonFactory.getObject();newSingleton = true;}finally {
//					创建bean完成,把标志位清除afterSingletonCreation(beanName);}
//				加入一级缓存,remove2,3级缓存。if (newSingleton) {addSingleton(beanName, singletonObject);}}return singletonObject;}}

现在就来Debug这个循环依赖过程,直接在实例化所有非懒加载的单例Bean这里标记beanName为a的去更进,会走getBean()->doGetBean()

protected <T> T doGetBean(String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)throws BeansException {String beanName = transformedBeanName(name);Object bean;// Eagerly check singleton cache for manually registered singletons.
//	这里会调用第一个重载的getSingleton(a,true)一级缓存拿不到,a也还没被标记为正在创建,所以这里返回null,Object sharedInstance = getSingleton(beanName);if (sharedInstance != null && args == null) {if (logger.isDebugEnabled()) {if (isSingletonCurrentlyInCreation(beanName)) {logger.debug("Returning eagerly cached instance of singleton bean '" + beanName +"' that is not fully initialized yet - a consequence of a circular reference");}else {logger.debug("Returning cached instance of singleton bean '" + beanName + "'");}}
//			现在的sharedInstance是一个完整对象,有可能是factorybean这个实现类本身,还得拿到另一个对象。有2个对象, 一定是先创建实现类再通过getObject方法创建所需的对象bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);}else {// Fail if we're already creating this bean instance:// We're assumably within a circular reference.
//			当对象都是单例的时候会尝试解决循环依赖的问题,但是原型模式下如果存在循环依赖的情况,那么会直接抛异常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);if (parentBeanFactory instanceof AbstractBeanFactory) {return ((AbstractBeanFactory) parentBeanFactory).doGetBean(nameToLookup, requiredType, args, typeCheckOnly);}else 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);}}
//表示要创建beanif (!typeCheckOnly) {markBeanAsCreated(beanName);}try {
//				获取,检测,beandefinitionRootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);checkMergedBeanDefinition(mbd, beanName, args);// Guarantee initialization of beans that the current bean depends on.
//				存在依赖bean,需要递归实例化依赖的bean,相当于有顺序String[] dependsOn = mbd.getDependsOn();if (dependsOn != null) {for (String dep : dependsOn) {if (isDependent(beanName, dep)) {throw new BeanCreationException(mbd.getResourceDescription(), beanName,"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");}registerDependentBean(dep, beanName);try {getBean(dep);}catch (NoSuchBeanDefinitionException ex) {throw new BeanCreationException(mbd.getResourceDescription(), beanName,"'" + beanName + "' depends on missing bean '" + dep + "'", ex);}}}// Create bean instance.
//				是不是单例if (mbd.isSingleton()) {
//					这里调用第二个重载的getSingleton(a,ObjectFactory),核心有3步,1:一级缓存拿不到 2:将a标记为正在创建 3:调用getObject()去回调lamda表达式的createBean(beanName, mbd, args)去创建a 4:将a加入一级缓存,移除二三级缓存sharedInstance = getSingleton(beanName, () -> {try {return createBean(beanName, mbd, args);}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;}});
//					可能是factoryBeanbean = 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 {String scopeName = mbd.getScope();if (!StringUtils.hasLength(scopeName)) {throw new IllegalStateException("No scope name defined for bean ´" + beanName + "'");}Scope scope = this.scopes.get(scopeName);if (scope == null) {throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");}try {Object scopedInstance = scope.get(beanName, () -> {beforePrototypeCreation(beanName);try {return createBean(beanName, mbd, args);}finally {afterPrototypeCreation(beanName);}});bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);}catch (IllegalStateException ex) {throw new BeanCreationException(beanName,"Scope '" + scopeName + "' is not active for the current thread; consider " +"defining a scoped proxy for this bean if you intend to refer to it from a singleton",ex);}}}catch (BeansException ex) {cleanupAfterBeanCreationFailure(beanName);throw ex;}}// Check if required type matches the type of the actual bean instance.if (requiredType != null && !requiredType.isInstance(bean)) {try {T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType);if (convertedBean == null) {throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());}return convertedBean;}catch (TypeMismatchException ex) {if (logger.isDebugEnabled()) {logger.debug("Failed to convert bean '" + name + "' to required type '" +ClassUtils.getQualifiedName(requiredType) + "'", ex);}throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());}}return (T) bean;}

上面代码很长,主要是对两个重载方法getSingleton()的调用

  1. 这里会调用第一个重载的getSingleton(a,true)一级缓存拿不到,a也还没被标记为正在创建,所以这里返回null,
    Object sharedInstance = getSingleton(beanName);
  2. 这里调用第二个重载的getSingleton(a,ObjectFactory),核心有3步,1:一级缓存拿不到 2:将a标记为正在创建 3:调用getObject()去回调lamda表达式的createBean(beanName, mbd, args)去创建a 4:将a加入一级缓存,移除二三级缓存
    sharedInstance = getSingleton(beanName, () -> {
    try {
    return createBean(beanName, mbd, args);
    }

接下来就去走一下createBean()->doCreateBean()

protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)throws BeanCreationException {// Instantiate the bean.BeanWrapper instanceWrapper = null;if (mbd.isSingleton()) {instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);}if (instanceWrapper == null) {
//			创建bean实例instanceWrapper = createBeanInstance(beanName, mbd, args);}
//		拿到原始对象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;}}// Eagerly cache singletons to be able to resolve circular references// even when triggered by lifecycle interfaces like BeanFactoryAware.
//		表示是否提前暴露,是否存在存在循环依赖beanA 满足条件boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&isSingletonCurrentlyInCreation(beanName));if (earlySingletonExposure) {if (logger.isDebugEnabled()) {logger.debug("Eagerly caching bean '" + beanName +"' to allow for resolving potential circular references");}//放入三级缓存addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));}// Initialize the bean instance.
//		原始bean,接着进行属性填充初始化Object exposedObject = bean;try {
//			填充属性populateBean(beanName, mbd, instanceWrapper);
//			初始化前初始化和初始化后一系列的awareexposedObject = 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);}}if (earlySingletonExposure) {//一二级缓存能否拿到,能说明存在循环依赖且解决了,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;}

doCreateBean()主要做了以下几点

  1. 反射去实例化a拿到原始对象
  2. 将原始对象放入三级缓存
  3. populateBean()为a的属性进行赋值
  4. 如果是代理对象的话那么一级缓存里也要替换成同一个代理对象
    那么现在的核心流程来到了第3点,为a进行属性填充,a需要注入一个B类型的Bean,容器中还没有生产B,进而暂停a的赋值去生产b。
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {if (bw == null) {// 如果BeanWrapper对象为nullif (mbd.hasPropertyValues()) {// 有属性但是没对象,那往哪里注入...直接抛异常了throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");}else {// Skip property population phase for null instance.return;}}// Give any InstantiationAwareBeanPostProcessors the opportunity to modify the// state of the bean before properties are set. This can be used, for example,// to support styles of field injection.
//		拿到InstantiationAwareBeanPostProcessor后置处理器if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {//实例化后的后置操作for (BeanPostProcessor bp : getBeanPostProcessors()) {if (bp instanceof InstantiationAwareBeanPostProcessor) {InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {return;// 实例化后置处理器可以发出终止填充的命令,这点比较特别}}}}
// 2. 获取属性值PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);
// 3. 根据注入方式的不同可分为 通过 ①名称注入、②类型注入、③不自动注入/*** ①按名称注入,则pvs在步骤2时会获取到配置文件中配置注入的属性,同时在autowireByName又会进一步通过名称添加补充* ②按名称注入,则pvs在步骤2时会获取到配置文件中配置注入的属性,同时在autowireByType又会进一步通过类型添加补充* ③不开启自动注入,则在步骤2 pvs就可以获取到配置文件中注入的属性*/int resolvedAutowireMode = mbd.getResolvedAutowireMode();//		这里其实是针对xml文件的,我们使用注解的Mode默认是AutoWIRE_NOif (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) {MutablePropertyValues newPvs = new MutablePropertyValues(pvs);// Add property values based on autowire by name if applicable.if (resolvedAutowireMode == AUTOWIRE_BY_NAME) {autowireByName(beanName, mbd, bw, newPvs);}// Add property values based on autowire by type if applicable.if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) {autowireByType(beanName, mbd, bw, newPvs);}pvs = newPvs;}
// 是否存在InstantiationAwareBeanPostProcessors,也就是我们的Autowired注解的后置处理器boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();// 依赖检测boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);if (hasInstAwareBpps || needsDepCheck) {if (pvs == null) {pvs = mbd.getPropertyValues();}PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);if (hasInstAwareBpps) {/*** 4. 属性填充的后置处理器* @Autowired* private Inner inner;* 在这里使用AutowiredAnnotationBeanPostProcessor进行注入*/for (BeanPostProcessor bp : getBeanPostProcessors()) {if (bp instanceof InstantiationAwareBeanPostProcessor) {InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;//AutowiredAnnotationBeanPostProcessor就在这里解析pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);if (pvs == null) {return;}}}}if (needsDepCheck) {checkDependencies(beanName, mbd, filteredPds, pvs);}}if (pvs != null) {//填充属性值applyPropertyValues(beanName, mbd, bw, pvs);}}

跳过xml处理,直接来到AutowiredAnnotationBeanPostProcessor的postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);

public PropertyValues postProcessPropertyValues(PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeanCreationException {
//metadata存储了某个类,以及这个类里需要被依赖注入的element(标注了@Autowired,@Value等注解的方法或者成员变量)
//		findAutowiringMetadata这个方法不陌生的,之前已经分析了,是去收集对应注解并封装为InjectionMetadata对象放入到缓存,这里就是从缓存中拿到值,注入则是通过inject实现的:InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass(), pvs);try {//注入metadata.inject(bean, beanName, pvs);}catch (BeanCreationException ex) {throw ex;}catch (Throwable ex) {throw new BeanCreationException(beanName, "Injection of autowired dependencies failed", ex);}return pvs;}

metadata.inject(bean, beanName, pvs);去处理,会执行element.inject(target, beanName, pvs);

protected void inject(Object bean, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {Field field = (Field) this.member;Object value;if (this.cached) {value = resolvedCachedArgument(beanName, this.cachedFieldValue);//这里进去获得属性值}else {DependencyDescriptor desc = new DependencyDescriptor(field, this.required);desc.setContainingClass(bean.getClass());Set<String> autowiredBeanNames = new LinkedHashSet<>(1);Assert.state(beanFactory != null, "No BeanFactory available");TypeConverter typeConverter = beanFactory.getTypeConverter();try {value = beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter);}catch (BeansException ex) {throw new UnsatisfiedDependencyException(null, beanName, new InjectionPoint(field), ex);}synchronized (this) {if (!this.cached) {if (value != null || this.required) {this.cachedFieldValue = desc;registerDependentBeans(beanName, autowiredBeanNames);if (autowiredBeanNames.size() == 1) {String autowiredBeanName = autowiredBeanNames.iterator().next();if (beanFactory.containsBean(autowiredBeanName) &&beanFactory.isTypeMatch(autowiredBeanName, field.getType())) {this.cachedFieldValue = new ShortcutDependencyDescriptor(desc, autowiredBeanName, field.getType());}}}else {this.cachedFieldValue = null;}this.cached = true;}}}if (value != null) {ReflectionUtils.makeAccessible(field);field.set(bean, value);}}

关键的代码value = beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter);然后会进入 result = doResolveDependency(descriptor, requestingBeanName, autowiredBeanNames, typeConverter);也就是DefaultListableBeanFactory类

public Object doResolveDependency(DependencyDescriptor descriptor, @Nullable String beanName,@Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException {//				循环依赖代码就在这里,终于找到了instanceCandidate = descriptor.resolveCandidate(autowiredBeanName, type, this);}

最后来到getBean(b)去容器获取b

public Object resolveCandidate(String beanName, Class<?> requiredType, BeanFactory beanFactory)throws BeansException {return beanFactory.getBean(beanName);}

到这里我们已经走到了实例化a的属性填充部分,此时因为要去实例化b,所以暂停a的属性填充工作,先去实例化b。同理,现在去实例化b,和实例化a是一样的步骤,现在来到b的属性填充部分,需要去容器获取a的Bean,现在又来到了getBean(a)看看如何处理,结合上面第一次getBean(a)的流程看看啥区别,


  1. 第二次getBean(a)
  2. doGetBean(a)
  3. 来到了第一个重载的getSingeton(a,true)
	protected Object getSingleton(String beanName, boolean allowEarlyReference) {
//		一级缓存单例池拿Object singletonObject = this.singletonObjects.get(beanName);//如果一级缓存没拿到并且是否正在创建,第一次A还没有开始创建,false,singletonsCurrentlyInCreation:是否正在创建if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
//			进来了说明存在循环依赖synchronized (this.singletonObjects) {
//				从二级缓存获取singletonObject = this.earlySingletonObjects.get(beanName);//二级缓存也没拿到,尝试用三级缓存if (singletonObject == null && allowEarlyReference) {ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);if (singletonFactory != null) {//也就是调用getEarlyBeanRederence()方法singletonObject = singletonFactory.getObject();//放入二级缓存,删除三级缓存this.earlySingletonObjects.put(beanName, singletonObject);this.singletonFactories.remove(beanName);}}}}return singletonObject;}

第一次getBean(a)并没有进入if判断,因为a没有标记为正在创建,但是第二次就进来了,并且最终会调用singletonObject = singletonFactory.getObject();去三级缓存的getEarlyBeanRederence(),这个方法会拿到第一次getBean(a)保存的初始bean或者提前AOP的代理对象(里面会调用SmartInstantiationAwareBeanPostProcessor的后置处理器,实现类为AbstractAutoProxyCreator,这个类去处理AOP这块,如果没有AOP不需要进行代理,那么直接将原始Bean返回就行,后续讲),也就是说现在出现了循环依赖,我先把一个不完整的a给你来打断这个循环。所以这第二次getBean(a)直接返回了一个原始bean,那么现在b的属性填充给了一个原始a,b属性填充完毕,现在b已经完完全全生产完毕了,a也就能继续完成属性填充。

//			填充属性populateBean(beanName, mbd, instanceWrapper);
//			初始化前初始化和初始化后一系列的awareexposedObject = 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);}}if (earlySingletonExposure) {//一二级缓存能否拿到,能说明存在循环依赖且解决了,bean在二级缓存,如果是代理对象,需要把这个代理对象放入一级缓存Object earlySingletonReference = getSingleton(beanName, false);

属性填充后就是初始化后处理,涉及AOP,然后还会调用一次第一个重载的getSingleton(beanName, false),注意第二个参数为false。那么他是干什么的呢。根据getSingleton()的逻辑发现他是去二级缓存拿,因为二级缓存里有可能是一个代理对象,所以我们放入一级缓存里的对象也应该是这个代理对象而不是反射出来的bean。

总结:

利用三级缓存解决循环依赖,体现在两个重载的getSingleton()方法。

AOP引入:
处理循环依赖是给他赋值一个不完整的bean对象,但是如果这个依赖的是一个代理对象呢,代理对象需要在初始化后才会进行,所以我们需要提前进行AOP,处理逻辑在三级缓存的getEarlyBeanRederence()
了解到调用SmartInstantiationAwareBeanPostProcessor的后置处理器,实现类为AbstractAutoProxyCreator,这个类去处理AOP这块。将这个属性赋值为一个代理对象后,利用二级缓存保证后面加入一级缓存也是同一个代理对象,后续详细介绍

本文链接:https://my.lmcjl.com/post/8409.html

展开阅读全文

4 评论

留下您的评论.