2024-06-17-Spring 原始碼閱讀(三)Bean 的生命週期

LinweiWang發表於2024-06-17

由於 Spring 原始碼非常多,部落格中貼原始碼會佔用大量篇幅,閱讀困難。詳細分析部分會以 commit 提交形式關聯原始碼提交,畫圖例來說明原始碼整體邏輯。

Bean 生命週期主體邏輯

相關程式碼:Bean的基本建立流程、lazyInit、迴圈依賴

Bean 物件建立基本流程

透過最開始的關鍵時機點分析,我們知道Bean建立⼦流程⼊⼝在 AbstractApplicationContext#refresh() ⽅法的 finishBeanFactoryInitialization(beanFactory) 處執行的。

整體呼叫順序如下:

AbstractApplicationContext#refresh
    AbstractApplicationContext#finishBeanFactoryInitialization
        DefaultListableBeanFactory#preInstantiateSingletons
            AbstractBeanFactory#getBean
                AbstractBeanFactory#doGetBean
                    DefaultSingletonBeanRegistry#getSingleton
                    AbstractAutowireCapableBeanFactory#createBean
                        AbstractAutowireCapableBeanFactory#doCreateBean

我們從 AbstractApplicationContext#finishBeanFactoryInitialization 開始分析

	protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
		// Initialize conversion service for this context.
		if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
				beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
			beanFactory.setConversionService(
					beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
		}

		// Register a default embedded value resolver if no BeanFactoryPostProcessor
		// (such as a PropertySourcesPlaceholderConfigurer bean) registered any before:
		// at this point, primarily for resolution in annotation attribute values.
		if (!beanFactory.hasEmbeddedValueResolver()) {
			beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
		}

		// Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.
		String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
		for (String weaverAwareName : weaverAwareNames) {
			getBean(weaverAwareName);
		}

		// Stop using the temporary ClassLoader for type matching.
		beanFactory.setTempClassLoader(null);

		// Allow for caching all bean definition metadata, not expecting further changes.
		beanFactory.freezeConfiguration();

		// 例項化所有立即載入的單例 Bean
		// Instantiate all remaining (non-lazy-init) singletons.
		beanFactory.preInstantiateSingletons();
	}

DefaultListableBeanFactory#preInstantiateSingletons

	@Override
	public void preInstantiateSingletons() throws BeansException {
		if (logger.isTraceEnabled()) {
			logger.trace("Pre-instantiating singletons in " + this);
		}

		// 存放 BeanNames
		// Iterate over a copy to allow for init methods which in turn register new bean definitions.
		// While this may not be part of the regular factory bootstrap, it does otherwise work fine.
		List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);

		// 觸發所有非延遲載入單例 Bean 的初始化,主要步驟是 getBean
		// Trigger initialization of all non-lazy singleton beans...
		for (String beanName : beanNames) {
			// 合併父 BeanDefinition 物件
			RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
			if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
				// 工廠 Bean:&BeanName
				if (isFactoryBean(beanName)) {
					Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
					if (bean instanceof FactoryBean) {
						FactoryBean<?> factory = (FactoryBean<?>) bean;
						boolean isEagerInit;
						if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
							isEagerInit = AccessController.doPrivileged(
									(PrivilegedAction<Boolean>) ((SmartFactoryBean<?>) factory)::isEagerInit,
									getAccessControlContext());
						}
						else {
							isEagerInit = (factory instanceof SmartFactoryBean &&
									((SmartFactoryBean<?>) factory).isEagerInit());
						}
						if (isEagerInit) {
							getBean(beanName);
						}
					}
				}
				else { // 例項化 Bean
					getBean(beanName);
				}
			}
		}

		// Trigger post-initialization callback for all applicable beans...
		for (String beanName : beanNames) {
			Object singletonInstance = getSingleton(beanName);
			if (singletonInstance instanceof SmartInitializingSingleton) {
				StartupStep smartInitialize = getApplicationStartup().start("spring.beans.smart-initialize")
						.tag("beanName", beanName);
				SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
				if (System.getSecurityManager() != null) {
					AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
						smartSingleton.afterSingletonsInstantiated();
						return null;
					}, getAccessControlContext());
				}
				else {
					smartSingleton.afterSingletonsInstantiated();
				}
				smartInitialize.end();
			}
		}
	}

AbstractBeanFactory#getBeanAbstractBeanFactory#doGetBean

	@Override
	public Object getBean(String name) throws BeansException {
		return doGetBean(name, null, null, false);
	}

	protected <T> T doGetBean(
			String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)
			throws BeansException {

		// 解析 BeanName,如果以 & 開頭則去掉 & ,如果是別名則獲取到真正的名字
		String beanName = transformedBeanName(name);
		Object beanInstance;

		// 從快取獲取 Bean(注意點:三級快取)
		// 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 + "'");
				}
			}
			// 針對 FactoryBean 做處理
			beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, null);
		}

		else {
			// prototype 型別的 Bean 不支援迴圈依賴
			// 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 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);
				}
				// 合併父子 Bean 屬性
				RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
				checkMergedBeanDefinition(mbd, beanName, args);

				// 處理 dependsOn 配置
				// Guarantee initialization of beans that the current bean depends on.
				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);
						}
					}
				}

				// 建立 Bean 例項
				// Create bean instance.
				if (mbd.isSingleton()) {
					// 單例
					sharedInstance = getSingleton(beanName, () -> {
						try {
							// 建立 Bean
							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);
	}

DefaultSingletonBeanRegistry#getSingleton

	public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
		Assert.notNull(beanName, "Bean name must not be null");
		synchronized (this.singletonObjects) {
			// 叢單例池中獲取 Bean
			Object singletonObject = this.singletonObjects.get(beanName);
			if (singletonObject == null) {
				// 是否正在銷燬,異常
				if (this.singletonsCurrentlyInDestruction) {
					throw new BeanCreationNotAllowedException(beanName,
							"Singleton bean creation not allowed while singletons of this factory are in destruction " +
							"(Do not request a bean from a BeanFactory in a destroy method implementation!)");
				}
				if (logger.isDebugEnabled()) {
					logger.debug("Creating shared instance of singleton bean '" + beanName + "'");
				}
				// 驗證完真正開始建立物件,先標識該 Bean 正在被建立
				beforeSingletonCreation(beanName);
				boolean newSingleton = false;
				boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
				if (recordSuppressedExceptions) {
					this.suppressedExceptions = new LinkedHashSet<>();
				}
				try {
					// 傳進來的 Lambda 表示式: singletonFactory ,並呼叫 getObject
					// (即上一步驟中的 () -> { try { return createBean(beanName, mbd, args); } catch (BeansException ex) { ... } })
					singletonObject = singletonFactory.getObject();
					newSingleton = true;
				}
				catch (IllegalStateException ex) {
					// Has the singleton object implicitly appeared in the meantime ->
					// if yes, proceed with it since the exception indicates that state.
					singletonObject = this.singletonObjects.get(beanName);
					if (singletonObject == null) {
						throw ex;
					}
				}
				catch (BeanCreationException ex) {
					if (recordSuppressedExceptions) {
						for (Exception suppressedException : this.suppressedExceptions) {
							ex.addRelatedCause(suppressedException);
						}
					}
					throw ex;
				}
				finally {
					if (recordSuppressedExceptions) {
						this.suppressedExceptions = null;
					}
					afterSingletonCreation(beanName);
				}
				if (newSingleton) {
					addSingleton(beanName, singletonObject);
				}
			}
			return singletonObject;
		}
	}

AbstractAutowireCapableBeanFactory#createBeanAbstractAutowireCapableBeanFactory#doCreateBean

	protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
			throws BeanCreationException {

		if (logger.isTraceEnabled()) {
			logger.trace("Creating instance of bean '" + beanName + "'");
		}
		// 拿到 mbd
		RootBeanDefinition mbdToUse = mbd;

		// Make sure bean class is actually resolved at this point, and
		// clone the bean definition in case of a dynamically resolved Class
		// which cannot be stored in the shared merged bean definition.
		Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
		if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
			mbdToUse = new RootBeanDefinition(mbd);
			mbdToUse.setBeanClass(resolvedClass);
		}

		// Prepare method overrides.
		try {
			mbdToUse.prepareMethodOverrides();
		}
		catch (BeanDefinitionValidationException ex) {
			throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
					beanName, "Validation of method overrides failed", ex);
		}

		try {
			// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
			Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
			if (bean != null) {
				return bean;
			}
		}
		catch (Throwable ex) {
			throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
					"BeanPostProcessor before instantiation of bean failed", ex);
		}

		try {
			// doCreateBean 方法進行建立 Bean
			Object beanInstance = doCreateBean(beanName, mbdToUse, args);
			if (logger.isTraceEnabled()) {
				logger.trace("Finished creating instance of bean '" + beanName + "'");
			}
			return beanInstance;
		}
		catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {
			// A previously detected exception with proper bean creation context already,
			// or illegal singleton state to be communicated up to DefaultSingletonBeanRegistry.
			throw ex;
		}
		catch (Throwable ex) {
			throw new BeanCreationException(
					mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
		}
	}

	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.
		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));
		}

		// 初始化 Bean 例項:屬性填充
		// Initialize the bean instance.
		Object exposedObject = bean;
		try {
			// 屬性填充
			populateBean(beanName, mbd, instanceWrapper);
			// 呼叫初始化方法,引用 BeanPostProcessor 後置處理器
			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)) {
					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;
	}

lazy-init 載入機制的基本流程

在配置檔案中設定 lazy-init

<bean id="person" class="io.github.linweiwang.bean.Person" lazy-init="true">
</bean>

DefaultListableBeanFactory#preInstantiateSingletonsif (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) { 可知 lazy-init 的 Bean 在容器啟動時是不會進行例項化的,通常是第⼀次進⾏ context.getBean() 時進⾏觸發

整體呼叫順序如下:

AbstractApplicationContext#getBean
    DefaultListableBeanFactory#getBean(Class<T> requiredType)
        DefaultListableBeanFactory#getBean
            DefaultListableBeanFactory#resolveBean
                DefaultListableBeanFactory#resolveNamedBean
                    DefaultListableBeanFactory#resolveNamedBean
                        AbstractBeanFactory#getBean
                            AbstractBeanFactory#doGetBean
            

DefaultListableBeanFactory#resolveNamedBean

	@Nullable
	private <T> NamedBeanHolder<T> resolveNamedBean(
			String beanName, ResolvableType requiredType, @Nullable Object[] args) throws BeansException {
        // AbstractBeanFactory#getBean 裡面會呼叫 doGetBean
		Object bean = getBean(beanName, null, args);
		if (bean instanceof NullBean) {
			return null;
		}
		return new NamedBeanHolder<T>(beanName, adaptBeanInstance(beanName, bean, requiredType.toClass()));
	}

迴圈依賴基本流程

迴圈依賴其實就是迴圈引⽤,也就是兩個或者兩個以上的 Bean 互相持有對⽅,最終形成閉環。⽐如A 依賴於B,B 依賴於 C,C ⼜依賴於 A。

單例 Bean 構造器引數迴圈依賴(⽆法解決)只能丟擲 BeanCurrentlyInCreationException 異常。

Prototype 原型 Bean迴圈依賴(⽆法解決)對於原型 Bean 的初始化過程中不論是透過構造器引數迴圈依賴還是透過 setXxx ⽅法產⽣迴圈依賴,Spring 都會直接報錯處理。

單例 Bean 的Field 屬性的迴圈依賴(可以解決),Spring 採⽤的是提前暴露物件的⽅法(也即三級快取)。

示例

	<bean id="a" class="io.github.linweiwang.bean.A">
		<property name="b" ref="b"/>
	</bean>
	<bean id="b" class="io.github.linweiwang.bean.B">
		<property name="a" ref="a"/>
	</bean>

AbstractAutowiredCapableBeanFactory#doGetBean() 入手

		// 處理迴圈依賴:單例、允許迴圈依賴
		// 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));
		}
		// 初始化 Bean 例項:屬性填充
		// Initialize the bean instance.
		Object exposedObject = bean;
		try {
			// 屬性填充
			populateBean(beanName, mbd, instanceWrapper);
			// 呼叫初始化方法,引用 BeanPostProcessor 後置處理器
			exposedObject = initializeBean(beanName, exposedObject, mbd);
		}

AbstractAutowiredCapableBeanFactory#populateBean

		if (pvs != null) {
			// 處理屬性
			applyPropertyValues(beanName, mbd, bw, pvs);
		}

AbstractAutowiredCapableBeanFactory#applyPropertyValues

				String propertyName = pv.getName();
				Object originalValue = pv.getValue();
				if (originalValue == AutowiredPropertyMarker.INSTANCE) {
					Method writeMethod = bw.getPropertyDescriptor(propertyName).getWriteMethod();
					if (writeMethod == null) {
						throw new IllegalArgumentException("Autowire marker for property without write method: " + pv);
					}
					originalValue = new DependencyDescriptor(new MethodParameter(writeMethod, 0), true);
				}
				// 真正去處理屬性值
				Object resolvedValue = valueResolver.resolveValueIfNecessary(pv, originalValue);
				Object convertedValue = resolvedValue;
				boolean convertible = bw.isWritableProperty(propertyName) &&
						!PropertyAccessorUtils.isNestedOrIndexedProperty(propertyName);
				if (convertible) {
					convertedValue = convertForProperty(resolvedValue, propertyName, bw, converter);
				}

BeanDefinitionValueResolver#resolveValueIfNecessary

		// 檢查屬性是否需要執行時引用另外一個 Bean
		// We must check each value to see whether it requires a runtime reference
		// to another bean to be resolved.
		if (value instanceof RuntimeBeanReference) {
			RuntimeBeanReference ref = (RuntimeBeanReference) value;
			return resolveReference(argName, ref);
		}

BeanDefinitionValueResolver#resolveReference

					// 獲取 Bean
					resolvedName = String.valueOf(doEvaluate(ref.getBeanName()));
					bean = this.beanFactory.getBean(resolvedName);

繼續呼叫 AbstarctBeanFactory#getBean 這時候要建立引用的 Bean 即 B。

整體呼叫流程為:

AbstractAutowiredCapableBeanFactory#doGetBean()
    DefaultSingletonBeanRegistry#addSingletonFactory // 加入三級快取
    AbstractAutowiredCapableBeanFactory#populateBean // 屬性填充
        AbstractAutowiredCapableBeanFactory#applyPropertyValues
            BeanDefinitionValueResolver#resolveValueIfNecessary
                BeanDefinitionValueResolver#resolveReference
                    AbstarctBeanFactory#getBean
    

下面進入迴圈:即建立 B 的過程中,需要 A:

建立 B 的時候,發現需要依賴 A,此時 B 依然需經歷上述步驟,為了獲取 A 到了 this.beanFactory.getBean(resolvedName)

注意此時處於 B 的初始化過程,B 需要獲取 A 。在這個過程中:由於此時 A 已經在三級快取中了,在獲取 A 的 doGetBean 過程中 Object sharedInstance = getSingleton(beanName); 會從快取中獲取 A。獲取到之後返回給 B。

DefaultSingletonBeanRegistry#getSingleton

	protected Object getSingleton(String beanName, boolean allowEarlyReference) {
		// Quick check for existing instance without full singleton lock
		// 從一級快取 singletonObjects 獲取
		Object singletonObject = this.singletonObjects.get(beanName);
		if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
			// 從二級快取 earlySingletonObjects 獲取
			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) {
							// 從三級快取 singletonFactories 獲取
							ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
							if (singletonFactory != null) {
								singletonObject = singletonFactory.getObject();
								// 從三級快取 singletonFactories 轉移至 二級快取 earlySingletonObjects
								this.earlySingletonObjects.put(beanName, singletonObject);
								this.singletonFactories.remove(beanName);
							}
						}
					}
				}
			}
		}
		return singletonObject;
	}

此時 B 已經獲取到所有屬性後已經完全裝配了,在 DefaultSingletonBeanRegistry#getSingleton 中呼叫 addSingleton(beanName, singletonObject);

DefaultSingletonBeanRegistry#addSingleton

	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);
		}
	}

此時 B 已經建立完成。 A 後續也獲取到 B 完成建立。

從上述過程中可以分析構造方法的注入是無法迴圈依賴的,因為無法提前建立出 A 或者 B 放入快取中。(new 一個物件即便不設定任何屬性值也需要呼叫其構造方法)。

Bean 生命週期詳細分析

所有增強器的建立和呼叫可以透過在每個方法打斷點,透過分析堆疊資訊來分析。

BeanFactory 後置增強

BeanFactory 的後置增強位於 AbstractApplicationContext#invokeBeanFactoryPostProcessors(beanFactory)

此部分對應 BeanFactory 和 Bean 的後置增強實現。首先分析下三種後置增強處理器的核心介面

  • BeanFactoryPostProcessor:BeanFactory 的後置增強處理器
    • BeanDefinitionRegistryPostProcessor
  • BeanPostProcessor:Bean 的後置增強處理器,可以改變 Bean
    • InstantiationAwareBeanPostProcessor
      • SmartInstantiationAwareBeanPostProcessor
    • MergedBeanDefinitionPostProcessor
    • DestructionAwareBeanPostProcessor
  • InitializingBean:Bean 初始化進行後續設定

自定義增強器實現上述結構,並 override 上述介面中的方法。 以某一個 Bean 的建立為例子。
相關程式碼:BeanFactory 和 Bean 的後置增強處理

image

Spring 底層預設會有一個 BeanDefinitionRegistryPostProcessor 類即:org.springframework.context.annotation.internalConfigurationAnnotationProcessor 型別為 ConfigurationClassPostProcessor 並且實現了 PriorityOrdered 介面。核心方法 ConfigurationClassPostProcessor#doProcessConfigurationClass,用於解析 @Configuration 配置類,參考程式碼 ConfigurationClassPostProcessor 解析配置類

image

註冊 Bean 後置增強器

Bean 的後置增強的建立位於 AbstractApplicationContext#registerBeanPostProcessors(beanFactory) 此處僅作建立,不會呼叫增強器的方法,參考程式碼 Bean 後置增強器的建立

image

呼叫 Bean 的 SmartInstantiationAwareBeanPostProcessors#predictBeanType 後置增強器的方法

Bean 的後置增強的呼叫位於 AbstractApplicationContext#registerListeners() 。相關原始碼:SmartInstantiationAwareBeanPostProcessors#predictBeanType 的執行

image

初始化建立非懶載入的 Bean

AbstractApplicationContext#finishBeanFactoryInitialization(beanFactory) 相關原始碼: 初始化建立非懶載入的 Bean
image

AbstractAutowiredCapableBeanFactory#createBean

這一步真正的去建立 Bean,核心呼叫邏輯 doCreateBean ,相關原始碼: doCreateBean 核心邏輯

createBeanInstance

image

三次快取的處理(後續詳細分析)和 createBeanInstance

image

initializeBean

image

相關文章