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注解:
- 首先会调用isDependent()方法通过dependentBeanMap判断是否出现循环依赖;
- 出现循环依赖直接报错;
- 如果没有出现循环依赖;
- 先记录依赖关系;
- 然后调用getBean()方法获取Bean对象信息;
循环依赖 ~ 属性相互依赖
@Component
public class AutowiredBeanOne {
@Autowired
private AutowiredBeanTwo autowiredBeanTwo;
}
@Component
public class AutowiredBeanTwo {
@Autowired
private AutowiredBeanOne autowiredBeanOne;
}
上述伪代码中的循环依赖,大致分四种情况:
- AutowiredBeanOne 原型、AutowiredBeanTwo 原型:spring无法解决这种循环依赖
- AutowiredBeanOne 原型、AutowiredBeanTwo 单例:三级缓存解决
- AutowiredBeanOne 单例、AutowiredBeanTwo 原型:三级缓存解决
- AutowiredBeanOne 单例、AutowiredBeanTwo 单例:三级缓存解决
三级缓存
三级缓存是通用的叫法。
- 一级缓存为:singletonObjects
- singletonObjects中缓存**的是已经经历了完整生命周期的bean对象。
- 二级缓存为:earlySingletonObjects**
- earlySingletonObjects比singletonObjects多了一个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 原型
- 首先我们在创建AutowiredBeanOne Bean对象的过程中会调用doGetBean()方法;
- 在doGetBean()方法中,首先从单例池获取对象,获取不到走下面 else 代码块;
- else 代码块第一步调用isPrototypeCurrentlyInCreation()方法判断是否是正在创建的原型Bean;现在 AutowiredBeanOne Bean对象不是正在创建中的Bean对象,跳过这个if判断;
- 再往下,会进去 mbd.isPrototype() 判断的 if 代码块;
- 调用beforePrototypeCreation()方法,记录AutowiredBeanOne Bean对象正在创建中;
- 然后这里调用createBean()方法去创建AutowiredBeanOne Bean对象;
- AutowiredBeanOne Bean对象实例化后,进行属性填充,通过依赖注入找到AutowiredBeanTwo,但是这时AutowiredBeanTwo还没有实例化;
- 调用doGetBean()方法创建AutowiredBeanTwo Bean对象;
- 单例池中获取不到走下面 else 代码块;
- else 代码块第一步调用isPrototypeCurrentlyInCreation()方法判断是否是正在创建的原型Bean;现在AutowiredBeanTwo Bean对象不是正在创建中的Bean对象,跳过这个if判断;
- 再往下,会进去 mbd.isPrototype() 判断的 if 代码块;
- 调用beforePrototypeCreation()方法,记录AutowiredBeanTwo Bean对象正在创建中;
- 然后这里调用createBean()方法去创建AutowiredBeanTwo Bean对象;
- AutowiredBeanTwo Bean对象实例化后,进行属性填充,通过依赖注入找到AutowiredBeanOne,但是这时AutowiredBeanOne 还没有实例化;
- 调用doGetBean()方法创建AutowiredBeanOne Bean对象;
- 单例池中获取不到走下面 else 代码块;
- else 代码块第一步调用isPrototypeCurrentlyInCreation()方法判断是否是正在创建的原型Bean;现在AutowiredBeanOne Bean对象是正在创建中的Bean对象,进入这个if判断,抛一个异常并提示:Requested bean is currently in creation: Is there an unresolvable circular reference?
- 这种情况可以通过在属性添加@Lazy解决,具体原理参开依赖注入;
情况2、源码推演
AutowiredBeanOne 原型、AutowiredBeanTwo 单例
- Spring容器在启动时会将所有添加@Component注解的类扫描成BeanDefinition;
- 扫描完成后会创建所有的懒加载、单例Bean;
- 这时会先创建AutowiredBeanTwo Bean对象;
- 调用doGetBean()方法获取AutowiredBeanTwo Bean对象;
- 在doGetBean()方法中首先调用getSingleton()方法获取,这里因为还没有创建过所以获取不到;
- 再往下进入mbd.isSingleton()判断的 if 代码块,然后调用doCreateBean()方法去创建AutowiredBeanTwo Bean对象;
- 在doCreateBean()方法中,首先调用createBeanInstance()方法进行实例化;
- 然后调用PostProcessors的后置处理;
- 再往下有一个判断,如果当前BeanDefinition是单例的 且 自动解决循环依赖的开关是开启动的 且 当前Bean是正在创建的;
- 此时AutowiredBeanTwo Bean对象,正好满足上面三个判断;
- 进入if判断后调用addSingletonFactory()方法;
- 在addSingletonFactory()方法中会在三级缓存中保存一个lambda表达式(也可以理解为这里放啦一个new出来的空对象);
- 再往下进行属性填充;
- 这时发现需要AutowiredBeanOne Bean对象;
- 然后调用doGetBean()方法获取AutowiredBeanOne Bean对象;
- 在doGetBean()方法中进入mbd.isPrototype()判断的 if 逻辑代码块;
- 然后调用doCreateBean()方法创建AutowiredBeanOne Bean对象;
- 实例化后进入属性填充,这是发现需要AutowiredBeanTwo Bean对象;
- 调用doGetBean()方法去获取AutowiredBeanTwo Bean对象;
- 进入doGetBean()方法后,调用getSingleton()方法;
- 进入getSingleton()方法,单例池中不存在 且 是正在创建的Bean对象;
- 依次从单例池(singletonObjects)、二级缓存(earlySingletonObjects)、三级缓存(singletonFactories)中获取,在三级缓存中获取到之后会赋值给二级缓存,并清空三级缓存;
- 这里冲缓存中获取到的是一个lambda表达式(也可以理解为这里放啦一个new出来的空对象);
- 然后将这个lambda表达式(也可以理解为这里放啦一个new出来的空对象),赋值给AutowiredBeanOne Bean对象的属性,这时AutowiredBeanOne Bean对象创建成功;
- 然后将AutowiredBeanOne Bean对象赋值给AutowiredBeanTwo Bean对象;
- AutowiredBeanTwo Bean对象在getSingleton()方法的最后一步调用addSingleton()方法, 将AutowiredBeanTwo Bean对象放入一级缓存,清空二级缓存和三级缓存;
情况3、源码推演
AutowiredBeanOne 单例、AutowiredBeanTwo 原型
和 情况2 一样,spring启动时先创建非懒加载的单例Bean,所以会先创建AutowiredBeanOne Bean对象,详细解决步骤参考 情况2
情况4、源码推演
AutowiredBeanOne 单例、AutowiredBeanTwo 单例
- spring容器启动后会先创建AutowiredBeanOne Bean对象实例化前会判断单例池中没有,且不是正在创建的Bean,然后实例化、AutowiredBeanOne Bean对象实例化后会在三级缓存中存储一段lambda表达式,lambda表达式的返回结果可能是实例对象,也可能是代理对象,然后AutowiredBeanOne Bean对象进行属性填充,
- 这时候发现需要AutowiredBeanTwo Bean对象,去创建AutowiredBeanTwo Bean对象实例化前也会判断单例池中不存在且不是正在创建的Bean,然后实例化,AutowiredBeanTwo Bean对象实例化后同样也会在三级缓存中存储一段lambda表达式,然后AutowiredBeanTwo Bean对象进行属性填充,
- 这时候发现需要AutowiredBeanOne Bean对象,去创建AutowiredBeanOne Bean对象再次判断单例池依然不存在,但是现在是正在创建中的Bean,二级缓存中没有,从三级缓存中获取,执行lambda表达式,如果需要代理就返回代理对象,不需要代理就返回实例对象,把返回实例放进二级缓存中,删除三级缓存,同时注入给AutowiredBeanTwo Bean对象的AutowiredBeanOne属性,AutowiredBeanTwo Bean对象实例化完成时初始化前、初始化、初始化后,这时判断AutowiredBeanTwo Bean对象如果需要切面的话生成代理对象(因为AutowiredBeanTwo Bean对象的三级缓存一直没有用到所以之间没有生成代理对象),不需要切面执行生成实例对象放进单例池;
- 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 通过属性自己注入自己
- 首先创建CirculateDependsOnOne Bean对象,在实例化后,进行属性注入,发现需要注入CirculateDependsOnOne Bean对象;
- 因为CirculateDependsOnOne Bean对象是原型的需要创建一个新的,在调用doGetBean()方法时,会判断是在线创建的原型Bean对报错;
情况二:单例Bean 通过属性自己注入自己
- 首先创建CirculateDependsOnOne Bean对象,在实例化后,属性注入之前,
- 有一个判断,如果当前BeanDefinition是单例的 且 自动解决循环依赖的开关是开启动的 且 当前Bean是正在创建的;
- 此时AutowiredBeanTwo Bean对象,正好满足上面三个判断;进入if判断后调用addSingletonFactory()方法;在addSingletonFactory()方法中会在三级缓存中保存一个lambda表达式(也可以理解为这里放啦一个new出来的空对象);
- 然后进行属性填充;
- 发现需要注入CirculateDependsOnOne Bean对象,从三级缓存中拿出lambda表达式(也可以理解为这里放啦一个new出来的空对象)进行注入;
- 这样可以解决通过属性自己注入自己的循环依赖;
情况三:单例Bean 通过构造器自己注入自己
- 首先创建CirculateDependsOnOne Bean对象,在实例化时,发现需要CirculateDependsOnOne Bean对象,但这时CirculateDependsOnOne Bean对象还没有实例化,会报错;
- 如果在构造器参数上添加@Lazy,创建CirculateDependsOnOne Bean对象,在实例化时,发现参数有@Lazy注解,会返回一个代理对象,这里可以解决单例Bean 通过构造器自己注入自己,循环依赖的问题;