spring循环依赖源码剖析(含面试)
循环依赖源码剖析:
protected <T> T doGetBean(
String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)
throws BeansException {
// 将 name 转换为 beanName
String beanName = transformedBeanName(name);
Object beanInstance;
// Eagerly check singleton cache for manually registered singletons.
// 尝试从缓存中获取 beanName 的 bean。单例模式
// 一共涉及到三个缓存:
// singletonObjects:单例对象缓存
// earlySingletonObjects:早期单例对象缓存
// singletonFactories:单例工厂缓存 k:beanName, v: ObjectFactory
// 一个对象刚刚创建的时候,这三个缓存中是没有值的。
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 + "'");
}
}
// 获取 Bean 实例的对象
beanInstance = 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);
}
// 检查此工厂中是否存在 bean 定义。
// 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 if (requiredType != null) {
// No args -> delegate to standard getBean method.
return parentBeanFactory.getBean(nameToLookup, requiredType);
}
else {
return (T) parentBeanFactory.getBean(nameToLookup);
}
}
// 调用doGetBean方法的时候,穿过来的typeCheckOnly=false
if (!typeCheckOnly) {
// 添加正在创建的bean的名称
// 底层是一个Set<String>集合
markBeanAsCreated(beanName);
}
StartupStep beanCreation = this.applicationStartup.start("spring.beans.instantiate")
.tag("beanName", name);
try {
if (requiredType != null) {
beanCreation.tag("beanType", requiredType::toString);
}
RootBeanDefinition 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 {
// 递归调用doGetBean方法
getBean(dep);
}
catch (NoSuchBeanDefinitionException ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"'" + beanName + "' depends on missing bean '" + dep + "'", ex);
}
}
}
// Create bean instance.
if (mbd.isSingleton()) {
sharedInstance = getSingleton(beanName, () -> {
try {
// 开始创建 bean,底层调用docreateBean
// 底层会判断是否提早曝光,是会提早曝光的。
// 会执行如下操作:
// this.singletonFactories.put(beanName, singletonFactory);
//this.earlySingletonObjects.remove(beanName);
//this.registeredSingletons.add(beanName);
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()) {
// 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 {
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);
}
});
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();
}
}
// 类型转换检查
return adaptBeanInstance(name, beanInstance, requiredType);
}
1.也就是说第一次会创建出来a对象,但是a对象中的b属性值为null(半成品),然后会将key为a,value为lambda表达式放入到三级缓存中。
然后进行populateBean方法中进行属性填充,说白了就是开始创建B对象。
2.会创建出来b对象,但是b对象中的a属性值为null(半成品)。然后会将key为b,value为lambda表达式放入到三级缓存中。
然后进行populateBean方法中进行属性填充,说白了给b对象中的a属性进行复制。
3.这个时候会走到我们的lambda表达式中,我们之前创建好的半成品的a对象进行返回。同时将三级缓存中的a对象移除掉,将其放入到二级缓存中(说白了二级缓存中放的是一个半成品对象key:a,value:b属性为null)。
这个时候b对象就是一个完整的成品对象了。
4.将完整的成品的b对象放入到一级缓存中,同时将它从三级缓存中移除。
5.然后将半成品中的a对象的b属性进行赋值。这个时候a也成为了成品对象了。
6.最后将成品的a对象放到一级缓存中,将二级缓存中的a对象进行移除。
三个map结构中分别存储什么对象?
一级缓存:成品对象
二级缓存:半成品
三级缓存:lambda表达式
如果只有两个map结构,能否解决循环依赖的问题?
可以,但是有前提条件:不能包含aop的创建或者说不能有代理对象。