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对象进行移除。

RuntimeBeanReferance

image

image

image

image

三个map结构中分别存储什么对象?

一级缓存:成品对象

二级缓存:半成品

三级缓存:lambda表达式

如果只有两个map结构,能否解决循环依赖的问题?

可以,但是有前提条件:不能包含aop的创建或者说不能有代理对象。

posted on 2024-09-21 15:29  ~码铃薯~  阅读(15)  评论(0编辑  收藏  举报

导航