13、Spring之Bean生命周期~循环依赖

循环依赖

spring循环依赖大致分三种:@DependsOn注解两个类循环依赖、属性相互依赖、自己注入自己;

循环依赖 ~ @DependsOn注解

/**
 * Return an instance, which may be shared or independent, of the specified bean.
 *
 * @param name          the name of the bean to retrieve
 * @param requiredType  the required type of the bean to retrieve
 * @param args          arguments to use when creating a bean instance using explicit arguments
 *                      (only applied when creating a new instance as opposed to retrieving an existing one)
 * @param typeCheckOnly whether the instance is obtained for a type check,
 *                      not for actual use
 * @return an instance of the bean
 * @throws BeansException if the bean could not be created
 */
@SuppressWarnings("unchecked")
protected <T> T doGetBean(String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)
		throws BeansException {

	// name有可能是 &xxx 或者 xxx,如果name是&xxx,那么beanName就是xxx
	// name有可能传入进来的是别名,那么beanName就是id
	// 拿到真正的beanName
	String beanName = transformedBeanName(name);
	Object beanInstance;

	// Eagerly check singleton cache for manually registered singletons.
	// 先判断单例池中是否存在 再判断二级缓存是否存在 再判断三级缓存是否存在
	Object sharedInstance = getSingleton(beanName);
	// 判断单例池中是否存在
	if (sharedInstance != null && args == null) {

		if (logger.isTraceEnabled()) {
			if (isSingletonCurrentlyInCreation(beanName)) {
				logger.trace("Returning eagerly cached instance of singleton bean '" + beanName +
						"' that is not fully initialized yet - a consequence of a circular reference");
			} else {
				logger.trace("Returning cached instance of singleton bean '" + beanName + "'");
			}
		}
		// 如果sharedInstance是FactoryBean,那么就调用getObject()返回对象
		beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, null);
	} else {
		// Fail if we're already creating this bean instance:
		// We're assumably within a circular reference.
		// 判断是否是正在创建的原型bean  这里用到啦ThreadLocal
		if (isPrototypeCurrentlyInCreation(beanName)) {
			throw new BeanCurrentlyInCreationException(beanName);
		}

		// Check if bean definition exists in this factory.
		BeanFactory parentBeanFactory = getParentBeanFactory();
		// 如果 父BeanFactory有值   且 BeanDefinition不存在
		if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
			// Not found -> check parent.
			// &&&&xxx---->&xxx
			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 if (requiredType != null) {
				// No args -> delegate to standard getBean method.
				return parentBeanFactory.getBean(nameToLookup, requiredType);
			} else {
				return (T) parentBeanFactory.getBean(nameToLookup);
			}
		}

		if (!typeCheckOnly) {
			markBeanAsCreated(beanName);
		}

		StartupStep beanCreation = this.applicationStartup.start("spring.beans.instantiate")
				.tag("beanName", name);
		try {
			if (requiredType != null) {
				beanCreation.tag("beanType", requiredType::toString);
			}

			// 根据 beanName 获取到合并之后的BeanDefinition
			RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);

			// 检查BeanDefinition是不是Abstract的
			checkMergedBeanDefinition(mbd, beanName, args);

			// Guarantee initialization of beans that the current bean depends on.
			String[] dependsOn = mbd.getDependsOn();
			if (dependsOn != null) {
				// dependsOn表示当前beanName所依赖的,当前Bean创建之前dependsOn所依赖的Bean必须已经创建好了
				for (String dep : dependsOn) {
					// beanName是不是被dep依赖了,如果是则出现了循环依赖
					if (isDependent(beanName, dep)) {
						throw new BeanCreationException(mbd.getResourceDescription(), beanName,
								"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
					}
					// dep被beanName依赖了,存入dependentBeanMap中,dep为key,beanName为value
					registerDependentBean(dep, beanName);

					// 创建所依赖的bean
					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()) {
				// 单例bean创建逻辑

				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;
					}
				});
				beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
			} else if (mbd.isPrototype()) {
				// 原型bean创建逻辑

				// It's a prototype -> create a new instance.
				Object prototypeInstance = null;
				try {
					beforePrototypeCreation(beanName);
					prototypeInstance = createBean(beanName, mbd, args);
				} finally {
					afterPrototypeCreation(beanName);
				}
				beanInstance = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
			} else {
				// 其他作用域bean的创建逻辑
				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 {  // session.getAttriute(beaName)  setAttri
					Object scopedInstance = scope.get(beanName, () -> {
						beforePrototypeCreation(beanName);
						try {
							return createBean(beanName, mbd, args);
						} finally {
							afterPrototypeCreation(beanName);
						}
					});
					beanInstance = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
				} catch (IllegalStateException ex) {
					throw new ScopeNotActiveException(beanName, scopeName, ex);
				}
			}
		} catch (BeansException ex) {
			beanCreation.tag("exception", ex.getClass().toString());
			beanCreation.tag("message", String.valueOf(ex.getMessage()));
			cleanupAfterBeanCreationFailure(beanName);
			throw ex;
		} finally {
			beanCreation.end();
		}
	}

	// 检查通过name所获得到的beanInstance的类型是否是requiredType
	return adaptBeanInstance(name, beanInstance, requiredType);
}

  通过上述代码我们可以看到,@DependsOn注解两个类循环依赖,这种的循环依赖spring无法回直接报错,在判断scope属性,调用createBean()方法之前,如果当前Bean对象有@dependsOn注解:

  1. 首先会调用isDependent()方法通过dependentBeanMap判断是否出现循环依赖;
  2. 出现循环依赖直接报错;
  3. 如果没有出现循环依赖;
  4. 先记录依赖关系;
  5. 然后调用getBean()方法获取Bean对象信息;

循环依赖 ~ 属性相互依赖

@Component
public class AutowiredBeanOne {
	@Autowired
	private AutowiredBeanTwo autowiredBeanTwo;
}

@Component
public class AutowiredBeanTwo {
	@Autowired
	private AutowiredBeanOne autowiredBeanOne;
}

上述伪代码中的循环依赖,大致分四种情况:

  1. AutowiredBeanOne 原型、AutowiredBeanTwo 原型:spring无法解决这种循环依赖
  2. AutowiredBeanOne 原型、AutowiredBeanTwo 单例:三级缓存解决
  3. AutowiredBeanOne 单例、AutowiredBeanTwo 原型:三级缓存解决
  4. AutowiredBeanOne 单例、AutowiredBeanTwo 单例:三级缓存解决

三级缓存

三级缓存是通用的叫法。

  • 一级缓存为:singletonObjects
    • singletonObjects中缓存**的是已经经历了完整生命周期的bean对象。
  • 二级缓存为:earlySingletonObjects**
    • earlySingletonObjectssingletonObjects多了一个early,表示缓存的是早期的bean对象。早期是什么意思?表示Bean的生命周期还没走完就把这个Bean放入了earlySingletonObjects
  • 三级缓存为:singletonFactories
    • singletonFactories中缓存的是ObjectFactory,表示对象工厂,表示用来创建早期bean对象的工厂

接下来我们从源码层面分析一下:

doGetBean代码块

/**
 * Return an instance, which may be shared or independent, of the specified bean.
 *
 * @param name          the name of the bean to retrieve
 * @param requiredType  the required type of the bean to retrieve
 * @param args          arguments to use when creating a bean instance using explicit arguments
 *                      (only applied when creating a new instance as opposed to retrieving an existing one)
 * @param typeCheckOnly whether the instance is obtained for a type check,
 *                      not for actual use
 * @return an instance of the bean
 * @throws BeansException if the bean could not be created
 */
@SuppressWarnings("unchecked")
protected <T> T doGetBean(String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)
		throws BeansException {

	// name有可能是 &xxx 或者 xxx,如果name是&xxx,那么beanName就是xxx
	// name有可能传入进来的是别名,那么beanName就是id
	// 拿到真正的beanName
	String beanName = transformedBeanName(name);
	Object beanInstance;

	// Eagerly check singleton cache for manually registered singletons.
	// 先判断单例池中是否存在 再判断二级缓存是否存在 再判断三级缓存是否存在
	Object sharedInstance = getSingleton(beanName);
	// 判断单例池中是否存在
	if (sharedInstance != null && args == null) {

		if (logger.isTraceEnabled()) {
			if (isSingletonCurrentlyInCreation(beanName)) {
				logger.trace("Returning eagerly cached instance of singleton bean '" + beanName +
						"' that is not fully initialized yet - a consequence of a circular reference");
			} else {
				logger.trace("Returning cached instance of singleton bean '" + beanName + "'");
			}
		}
		// 如果sharedInstance是FactoryBean,那么就调用getObject()返回对象
		beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, null);
	} else {
		// Fail if we're already creating this bean instance:
		// We're assumably within a circular reference.
		// 判断是否是正在创建的原型bean  这里用到啦ThreadLocal
		if (isPrototypeCurrentlyInCreation(beanName)) {
			throw new BeanCurrentlyInCreationException(beanName);
		}

		// Check if bean definition exists in this factory.
		BeanFactory parentBeanFactory = getParentBeanFactory();
		// 如果 父BeanFactory有值   且 BeanDefinition不存在
		if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
			// Not found -> check parent.
			// &&&&xxx---->&xxx
			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 if (requiredType != null) {
				// No args -> delegate to standard getBean method.
				return parentBeanFactory.getBean(nameToLookup, requiredType);
			} else {
				return (T) parentBeanFactory.getBean(nameToLookup);
			}
		}

		if (!typeCheckOnly) {
			markBeanAsCreated(beanName);
		}

		StartupStep beanCreation = this.applicationStartup.start("spring.beans.instantiate")
				.tag("beanName", name);
		try {
			if (requiredType != null) {
				beanCreation.tag("beanType", requiredType::toString);
			}

			// 根据 beanName 获取到合并之后的BeanDefinition
			RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);

			// 检查BeanDefinition是不是Abstract的
			checkMergedBeanDefinition(mbd, beanName, args);

			// Guarantee initialization of beans that the current bean depends on.
			String[] dependsOn = mbd.getDependsOn();
			if (dependsOn != null) {
				// dependsOn表示当前beanName所依赖的,当前Bean创建之前dependsOn所依赖的Bean必须已经创建好了
				for (String dep : dependsOn) {
					// beanName是不是被dep依赖了,如果是则出现了循环依赖
					if (isDependent(beanName, dep)) {
						throw new BeanCreationException(mbd.getResourceDescription(), beanName,
								"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
					}
					// dep被beanName依赖了,存入dependentBeanMap中,dep为key,beanName为value
					registerDependentBean(dep, beanName);

					// 创建所依赖的bean
					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()) {
				// 单例bean创建逻辑

				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;
					}
				});
				beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
			} else if (mbd.isPrototype()) {
				// 原型bean创建逻辑

				// It's a prototype -> create a new instance.
				Object prototypeInstance = null;
				try {
					beforePrototypeCreation(beanName);
					prototypeInstance = createBean(beanName, mbd, args);
				} finally {
					afterPrototypeCreation(beanName);
				}
				beanInstance = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
			} else {
				// 其他作用域bean的创建逻辑
				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 {  // session.getAttriute(beaName)  setAttri
					Object scopedInstance = scope.get(beanName, () -> {
						beforePrototypeCreation(beanName);
						try {
							return createBean(beanName, mbd, args);
						} finally {
							afterPrototypeCreation(beanName);
						}
					});
					beanInstance = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
				} catch (IllegalStateException ex) {
					throw new ScopeNotActiveException(beanName, scopeName, ex);
				}
			}
		} catch (BeansException ex) {
			beanCreation.tag("exception", ex.getClass().toString());
			beanCreation.tag("message", String.valueOf(ex.getMessage()));
			cleanupAfterBeanCreationFailure(beanName);
			throw ex;
		} finally {
			beanCreation.end();
		}
	}

	// 检查通过name所获得到的beanInstance的类型是否是requiredType
	return adaptBeanInstance(name, beanInstance, requiredType);
}

doCreateBean代码块

/**
 * Actually create the specified bean. Pre-creation processing has already happened
 * at this point, e.g. checking {@code postProcessBeforeInstantiation} callbacks.
 * <p>Differentiates between default bean instantiation, use of a
 * factory method, and autowiring a constructor.
 *
 * @param beanName the name of the bean
 * @param mbd      the merged bean definition for the bean
 * @param args     explicit arguments to use for constructor or factory method invocation
 * @return a new instance of the bean
 * @throws BeanCreationException if the bean could not be created
 * @see #instantiateBean
 * @see #instantiateUsingFactoryMethod
 * @see #autowireConstructor
 */
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
		throws BeanCreationException {

	// 实例化bean
	// Instantiate the bean.
	BeanWrapper instanceWrapper = null;
	if (mbd.isSingleton()) {
		// 有可能在本Bean创建之前,就有其他Bean把当前Bean给创建出来了(比如依赖注入过程中)
		// factoryBeanObjectCache:存的是beanName对应的FactoryBean.getObject()所返回的对象
		// factoryBeanInstanceCache:存的是beanName对应的FactoryBean实例对象
		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;
	}

	// 后置处理合并后的BeanDefinition
	// 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.
	boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
			isSingletonCurrentlyInCreation(beanName));
	if (earlySingletonExposure) {
		if (logger.isTraceEnabled()) {
			logger.trace("Eagerly caching bean '" + beanName +
					"' to allow for resolving potential circular references");
		}
		// 循环依赖-添加到三级缓存
		addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
	}

	// Initialize the bean instance.
	Object exposedObject = bean;
	try {
		// 属性填充
		populateBean(beanName, mbd, instanceWrapper);

		// 初始化
		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);
		}
	}

	if (earlySingletonExposure) {
		Object earlySingletonReference = getSingleton(beanName, false);
		if (earlySingletonReference != null) {
			if (exposedObject == bean) {
				exposedObject = earlySingletonReference;
			} else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
				// beanName被哪些bean依赖了,现在发现beanName所对应的bean对象发生了改变,那么则会报错
				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;
}

getSingleton代码块

/**
 * Return the (raw) singleton object registered under the given name.
 * <p>Checks already instantiated singletons and also allows for an early
 * reference to a currently created singleton (resolving a circular reference).
 * @param beanName the name of the bean to look for
 * @param allowEarlyReference whether early references should be created or not
 * @return the registered singleton object, or {@code null} if none found
 */
@Nullable
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
	// Quick check for existing instance without full singleton lock
	Object singletonObject = this.singletonObjects.get(beanName);
	//单例池中不存在 且 是正在创建的单例对象
	if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
		singletonObject = this.earlySingletonObjects.get(beanName);
		if (singletonObject == null && allowEarlyReference) {
			synchronized (this.singletonObjects) {
				// Consistent creation of early reference within full singleton lock
				singletonObject = this.singletonObjects.get(beanName);
				if (singletonObject == null) {
					singletonObject = this.earlySingletonObjects.get(beanName);
					if (singletonObject == null) {
						ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
						if (singletonFactory != null) {
							singletonObject = singletonFactory.getObject();
							this.earlySingletonObjects.put(beanName, singletonObject);
							this.singletonFactories.remove(beanName);
						}
					}
				}
			}
		}
	}
	return singletonObject;
}

addSingletonFactory代码块

/**
 * Add the given singleton factory for building the specified singleton
 * if necessary.
 * <p>To be called for eager registration of singletons, e.g. to be able to
 * resolve circular references.
 * @param beanName the name of the bean
 * @param singletonFactory the factory for the singleton object
 */
protected void addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory) {
	Assert.notNull(singletonFactory, "Singleton factory must not be null");
	synchronized (this.singletonObjects) {
		if (!this.singletonObjects.containsKey(beanName)) {
			this.singletonFactories.put(beanName, singletonFactory);
			this.earlySingletonObjects.remove(beanName);
			this.registeredSingletons.add(beanName);
		}
	}
}

addSingleton代码块

/**
 * Add the given singleton object to the singleton cache of this factory.
 * <p>To be called for eager registration of singletons.
 * @param beanName the name of the bean
 * @param singletonObject the singleton object
 */
protected void addSingleton(String beanName, Object singletonObject) {
	synchronized (this.singletonObjects) {
		this.singletonObjects.put(beanName, singletonObject);
		this.singletonFactories.remove(beanName);
		this.earlySingletonObjects.remove(beanName);
		this.registeredSingletons.add(beanName);
	}
}

情况1、源码推演

AutowiredBeanOne 原型AutowiredBeanTwo 原型

  1. 首先我们在创建AutowiredBeanOne Bean对象的过程中会调用doGetBean()方法
  2. doGetBean()方法中,首先从单例池获取对象,获取不到走下面 else 代码块;
  3. else 代码块第一步调用isPrototypeCurrentlyInCreation()方法判断是否是正在创建的原型Bean;现在 AutowiredBeanOne Bean对象不是正在创建中的Bean对象,跳过这个if判断;
  4. 再往下,会进去 mbd.isPrototype() 判断的 if 代码块;
  5. 调用beforePrototypeCreation()方法,记录AutowiredBeanOne Bean对象正在创建中;
  6. 然后这里调用createBean()方法去创建AutowiredBeanOne Bean对象
  7. AutowiredBeanOne Bean对象实例化后,进行属性填充,通过依赖注入找到AutowiredBeanTwo,但是这时AutowiredBeanTwo还没有实例化;
  8. 调用doGetBean()方法创建AutowiredBeanTwo Bean对象
  9. 单例池中获取不到走下面 else 代码块;
  10. else 代码块第一步调用isPrototypeCurrentlyInCreation()方法判断是否是正在创建的原型Bean;现在AutowiredBeanTwo Bean对象不是正在创建中的Bean对象,跳过这个if判断;
  11. 再往下,会进去 mbd.isPrototype() 判断的 if 代码块;
  12. 调用beforePrototypeCreation()方法,记录AutowiredBeanTwo Bean对象正在创建中;
  13. 然后这里调用createBean()方法去创建AutowiredBeanTwo Bean对象
  14. AutowiredBeanTwo Bean对象实例化后,进行属性填充,通过依赖注入找到AutowiredBeanOne,但是这时AutowiredBeanOne 还没有实例化;
  15. 调用doGetBean()方法创建AutowiredBeanOne Bean对象
  16. 单例池中获取不到走下面 else 代码块;
  17. else 代码块第一步调用isPrototypeCurrentlyInCreation()方法判断是否是正在创建的原型Bean;现在AutowiredBeanOne Bean对象是正在创建中的Bean对象,进入这个if判断,抛一个异常并提示:Requested bean is currently in creation: Is there an unresolvable circular reference?
  18. 这种情况可以通过在属性添加@Lazy解决,具体原理参开依赖注入;

情况2、源码推演

AutowiredBeanOne 原型AutowiredBeanTwo 单例

  1. Spring容器在启动时会将所有添加@Component注解的类扫描成BeanDefinition;
  2. 扫描完成后会创建所有的懒加载、单例Bean;
  3. 这时会先创建AutowiredBeanTwo Bean对象
  4. 调用doGetBean()方法获取AutowiredBeanTwo Bean对象
  5. doGetBean()方法中首先调用getSingleton()方法获取,这里因为还没有创建过所以获取不到;
  6. 再往下进入mbd.isSingleton()判断的 if 代码块,然后调用doCreateBean()方法去创建AutowiredBeanTwo Bean对象
  7. doCreateBean()方法中,首先调用createBeanInstance()方法进行实例化;
  8. 然后调用PostProcessors的后置处理;
  9. 再往下有一个判断,如果当前BeanDefinition是单例的 且 自动解决循环依赖的开关是开启动的 且 当前Bean是正在创建的;
  10. 此时AutowiredBeanTwo Bean对象,正好满足上面三个判断;
  11. 进入if判断后调用addSingletonFactory()方法;
  12. addSingletonFactory()方法中会在三级缓存中保存一个lambda表达式(也可以理解为这里放啦一个new出来的空对象)
  13. 再往下进行属性填充;
  14. 这时发现需要AutowiredBeanOne Bean对象
  15. 然后调用doGetBean()方法获取AutowiredBeanOne Bean对象
  16. doGetBean()方法中进入mbd.isPrototype()判断的 if 逻辑代码块;
  17. 然后调用doCreateBean()方法创建AutowiredBeanOne Bean对象
  18. 实例化后进入属性填充,这是发现需要AutowiredBeanTwo Bean对象
  19. 调用doGetBean()方法去获取AutowiredBeanTwo Bean对象
  20. 进入doGetBean()方法后,调用getSingleton()方法;
  21. 进入getSingleton()方法,单例池中不存在 且 是正在创建的Bean对象;
  22. 依次从单例池(singletonObjects)、二级缓存(earlySingletonObjects)、三级缓存(singletonFactories)中获取,在三级缓存中获取到之后会赋值给二级缓存,并清空三级缓存
  23. 这里冲缓存中获取到的是一个lambda表达式(也可以理解为这里放啦一个new出来的空对象);
  24. 然后将这个lambda表达式(也可以理解为这里放啦一个new出来的空对象),赋值给AutowiredBeanOne Bean对象的属性,这时AutowiredBeanOne Bean对象创建成功;
  25. 然后将AutowiredBeanOne Bean对象赋值给AutowiredBeanTwo Bean对象
  26. AutowiredBeanTwo Bean对象在getSingleton()方法的最后一步调用addSingleton()方法, 将AutowiredBeanTwo Bean对象放入一级缓存,清空二级缓存和三级缓存

情况3、源码推演

AutowiredBeanOne 单例AutowiredBeanTwo 原型
情况2 一样,spring启动时先创建非懒加载的单例Bean,所以会先创建AutowiredBeanOne Bean对象,详细解决步骤参考 情况2

情况4、源码推演

AutowiredBeanOne 单例AutowiredBeanTwo 单例

  1. spring容器启动后会先创建AutowiredBeanOne Bean对象实例化前会判断单例池中没有,且不是正在创建的Bean,然后实例化、AutowiredBeanOne Bean对象实例化后会在三级缓存中存储一段lambda表达式,lambda表达式的返回结果可能是实例对象,也可能是代理对象,然后AutowiredBeanOne Bean对象进行属性填充,
  2. 这时候发现需要AutowiredBeanTwo Bean对象,去创建AutowiredBeanTwo Bean对象实例化前也会判断单例池中不存在且不是正在创建的Bean,然后实例化,AutowiredBeanTwo Bean对象实例化后同样也会在三级缓存中存储一段lambda表达式,然后AutowiredBeanTwo Bean对象进行属性填充,
  3. 这时候发现需要AutowiredBeanOne Bean对象,去创建AutowiredBeanOne Bean对象再次判断单例池依然不存在,但是现在是正在创建中的Bean,二级缓存中没有,从三级缓存中获取,执行lambda表达式,如果需要代理就返回代理对象,不需要代理就返回实例对象,把返回实例放进二级缓存中,删除三级缓存,同时注入给AutowiredBeanTwo Bean对象AutowiredBeanOne属性,AutowiredBeanTwo Bean对象实例化完成时初始化前、初始化、初始化后,这时判断AutowiredBeanTwo Bean对象如果需要切面的话生成代理对象(因为AutowiredBeanTwo Bean对象的三级缓存一直没有用到所以之间没有生成代理对象),不需要切面执行生成实例对象放进单例池;
  4. AutowiredBeanTwo Bean对象创建完成后,把AutowiredBeanTwo Bean对象赋值给AutowiredBeanOne Bean对象AutowiredBeanTwo属性,然后Bean进行初始化前、初始化、初始化后,这时候因为之前创建啦AutowiredBeanTwo Bean对象的实例对象或者代理对象,直接从二级缓存中拿出AutowiredBeanTwo Bean对象进行操作,创建完成删除二级缓存的AutowiredBeanTwo Bean对象,放进一级缓存(单例池)中。

循环依赖 ~ 自己注入自己

/**
 *	情况一:
 * 原型Bean 自己注入自己会报错
 */
@Component
@Scope(BeanDefinition.SCOPE_PROTOTYPE)
public class CirculateDependsOnOne {
	@Autowired
	private CirculateDependsOnOne circulateDependsOnOne;

}

/**
 * 情况二:
 * 单例Bean 通过属性自己注入自己 三级缓存可以解决
 */
@Component
@Scope(BeanDefinition.SCOPE_SINGLETON)
public class CirculateDependsOnOne {
	@Autowired
	private CirculateDependsOnOne circulateDependsOnOne;

}

/**
 * 情况三:
 * 单例Bean 通过构造器自己注入自己 三级缓存无法解决,可以添加@Lazy注解解决
 */
@Component
@Scope(BeanDefinition.SCOPE_SINGLETON)
public class CirculateDependsOnOne {
	private CirculateDependsOnOne circulateDependsOnOne;
	@Autowired
//	public CirculateDependsOnOne(@Lazy CirculateDependsOnOne circulateDependsOnOne) {
	public CirculateDependsOnOne(CirculateDependsOnOne circulateDependsOnOne) {
		this.circulateDependsOnOne = circulateDependsOnOne;
	}
}

情况一:原型Bean 通过属性自己注入自己

  1. 首先创建CirculateDependsOnOne Bean对象,在实例化后,进行属性注入,发现需要注入CirculateDependsOnOne Bean对象;
  2. 因为CirculateDependsOnOne Bean对象是原型的需要创建一个新的,在调用doGetBean()方法时,会判断是在线创建的原型Bean对报错;

情况二:单例Bean 通过属性自己注入自己

  1. 首先创建CirculateDependsOnOne Bean对象,在实例化后,属性注入之前,
  2. 有一个判断,如果当前BeanDefinition是单例的 且 自动解决循环依赖的开关是开启动的 且 当前Bean是正在创建的;
  3. 此时AutowiredBeanTwo Bean对象,正好满足上面三个判断;进入if判断后调用addSingletonFactory()方法;在addSingletonFactory()方法中会在三级缓存中保存一个lambda表达式(也可以理解为这里放啦一个new出来的空对象);
  4. 然后进行属性填充;
  5. 发现需要注入CirculateDependsOnOne Bean对象,从三级缓存中拿出lambda表达式(也可以理解为这里放啦一个new出来的空对象)进行注入;
  6. 这样可以解决通过属性自己注入自己的循环依赖;

情况三:单例Bean 通过构造器自己注入自己

  1. 首先创建CirculateDependsOnOne Bean对象,在实例化时,发现需要CirculateDependsOnOne Bean对象,但这时CirculateDependsOnOne Bean对象还没有实例化,会报错;
  2. 如果在构造器参数上添加@Lazy,创建CirculateDependsOnOne Bean对象,在实例化时,发现参数有@Lazy注解,会返回一个代理对象,这里可以解决单例Bean 通过构造器自己注入自己,循环依赖的问题;
  • 25
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值