Spring源碼系列 — Bean生命周期


前言

上篇文章中介紹了Spring容器的擴展點,這個是在Bean的創建過程之前執行的邏輯。承接擴展點之后,就是Spring容器的另一個核心:Bean的生命周期過程。這個生命周期過程大致經歷了一下的幾個階段

在本節中重點介紹實例化、填充裝配、喚醒Aware方法、BeanPostProcessor后置處理、初始化等過程。關於Bean的銷毀過程這里不再介紹。由於Bean的生命周期的維護過程實際上都是由BeanFactory負責,所以在開始Bean的生命周期過程詳解之前,先概覽性了解BeanFactory。本文目錄:

  • BeanFactory概覽
  • Bean的實例化
  • Bean的裝配
  • Bean的后置處理
  • Bean的初始化

BeanFactory概覽

簡單點說,BeanFactory就是Spring框架的內核,它負責Bean的整個生命周期的管理。在Spring中對該抽象出了一套BeanFactory的接口,仍然遵守接口隔離,單一職責原則。

Spring將BeanFactory抽象出了最頂層接口,主要提供給client一個Spring容器的視圖。
下面都是根據BeanFactory的功能進行划分拆分隔離出不同功能的Bean工廠:

  1. 具有層次的BeanFactory,存在父子關系
  2. 可羅列的BeanFactory,提供獲取Bean定義個數、獲取所有的Bean名稱、獲取所有Bean定義等等的可羅列的能力
  3. 具有裝配能力的BeanFactory,提供自動裝配Bean的能力,這個可謂是Spring的核心,自動裝配依賴注入
  4. 可配置的BeanFactory,提供配置父BeanFactory、類加載器、轉換服務等等能力

這一套BeanFactory可謂抽象的淋漓盡致。從這里也可以看出Spring設計上的優秀程度,也提現作者們的面向對象的思維和設計模式的功底。

再者就是實現,其中AbstractBeanFactory無疑是核心,它是BeanFactory的基本能力的實現,提供了以下幾點特性:

  1. 能夠獲取BeanDefinition,所以可以被實現可羅列的BeanFactory繼承擴展
  2. 提供基本的單例創建的模板方法doGetBean,同時繼承了SingletonBeanRegistry的實現DefaultSingletonBeanRegistry,從而具有單例緩存能力
  3. 實現了HierarchicalBeanFactory和ConfigurableBeanFactory接口,從而具有BeanFactory的層次能力,也具有配置BeanFactory的能力

AbstractAutowireCapableBeanFactory在AbstractBeanFactory的基礎上擴展實現AutowireCapableBeanFactory接口,從而具有裝配能力的BeanFactory。

DefaultListableBeanFactory是繼承AbstractAutowireCapableBeanFactory並且實現ListableBeanFactory接口,從而具有可羅列的功能。它也是Spring中核心實現。基本上所有的上下文都是通過持有該BeanFactory實現,從而具有管理Bean的能力。

為了更形象直觀的了解Bean的實現細節,先看下Bean的實例化、裝配、后置處理、初始化的時序圖:

Bean的實例化

Bean的實例化過程非常復雜,但是簡單的概括,也就一個邏輯:從BeanDefinition華麗的轉身至配置的Bean對象的過程,這節承接上篇文章擴展點,繼續看AbstractApplicationContext的模板方法refresh后續的實例化Bean的邏輯流程。關於Bean的屬性,如:Lazy-Init/Scope/Autowired Way等等,這里不再介紹,讀者可以移步至Spring官網翻閱文檔。

首先依然從源頭refresh的模板方法着手:

try {
	// Allows post-processing of the bean factory in context subclasses.
	postProcessBeanFactory(beanFactory);
	// Invoke factory processors registered as beans in the context.
	invokeBeanFactoryPostProcessors(beanFactory);
	// Register bean processors that intercept bean creation.
	registerBeanPostProcessors(beanFactory);
	
	... 忽略

	// 模板方法中,這一步完成Bean工廠中遺留下的非惰性的Bean的實例化
	// Instantiate all remaining (non-lazy-init) singletons.
	finishBeanFactoryInitialization(beanFactory);
	// Last step: publish corresponding event.
	finishRefresh();
}catch (BeansException ex) {
	... 忽略
}

finishBeanFactoryInitialization該方法是正式開始實例化應用配置的Bean的核心步驟(並不是所有的Bean都是這一步驟中實例化,如前篇文章中的那些擴張點,在這之前就已經實例化)

protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
	// 在實例化剩余的Bean之前,需要針對BeanFactory進行配置
	// 1. 配置BeanFactory的轉換service
	// 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 bean post-processor
	// (such as a PropertyPlaceholderConfigurer bean) registered any before:
	// at this point, primarily for resolution in annotation attribute values.
	if (!beanFactory.hasEmbeddedValueResolver()) {
		beanFactory.addEmbeddedValueResolver(new StringValueResolver() {
			@Override
			public String resolveStringValue(String strVal) {
				return getEnvironment().resolvePlaceholders(strVal);
			}
		});
	}
	// 過早實例化LoadTimeWeaverAware
	// 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);
	}
	// 停止使用temporary ClassLoader
	// Stop using the temporary ClassLoader for type matching.
	beanFactory.setTempClassLoader(null);
	// 凍結配置,已經在實例化階段且經過了BeanFactoryPostProcessor,不允許修改Bean定義
	// Allow for caching all bean definition metadata, not expecting further changes.
	beanFactory.freezeConfiguration();
	// 實例化遺留的非惰性單例Bean
	// Instantiate all remaining (non-lazy-init) singletons.
	beanFactory.preInstantiateSingletons();
}

preInstantiateSingletons是ConfigurableListableBeanFactory工廠接口抽象的接口,確保非惰性的單例能夠被實例化。默認實現是DefaultListableBeanFactory:

@Override
public void preInstantiateSingletons() throws BeansException {
	if (logger.isDebugEnabled()) {
		logger.debug("Pre-instantiating singletons in " + this);
	}
	// 在bean定義的拷貝上迭代,當是非規則的factory,初始化方法仍然能增加bean定義,也能正常規則
	// 非規則的factory,很少使用,這里不做太多關注
	// 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<String>(this.beanDefinitionNames);
	// 這里出發非惰性的單例的實例化
	// Trigger initialization of all non-lazy singleton beans...
	// 迭代每個bean名稱,按名稱逐個實例化
	for (String beanName : beanNames) {
		// 根據bean名稱獲取其對應的RootBeanDefinition
		RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
		// 當是非抽象,且是單例,非惰性bean,則進行初始化;否則迭代下一個bean
		if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
			// 判斷該名稱的bean是否為工廠bean
			if (isFactoryBean(beanName)) {
				// 是工廠bean,則先獲取該Bean對應的FactoryBean,在Spring中FactoryBean的名稱命名規則為:"&" + "beanName"
				final FactoryBean<?> factory = (FactoryBean<?>) getBean(FACTORY_BEAN_PREFIX + beanName);
				boolean isEagerInit;
				// 判斷該工廠Bean是否可以過早實例化
				// 標准的FactoryBean是不過早實例化的,只有在被調用進行實際訪問時才實例化
				// 而SmartFactoryBean提供了可以設置是否盡早實例化
				if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
					isEagerInit = AccessController.doPrivileged(new PrivilegedAction<Boolean>() {
						@Override
						public Boolean run() {
							return ((SmartFactoryBean<?>) factory).isEagerInit();
						}
					}, getAccessControlContext());
				}
				else {
					// 非SmartFactoryBean時,則不實例化;如果是,則判斷SmartFactoryBean的盡早實例化的設置參數
					isEagerInit = (factory instanceof SmartFactoryBean &&
							((SmartFactoryBean<?>) factory).isEagerInit());
				}
				// 如果非過早實例化,則迭代下一個Bean名稱
				if (isEagerInit) {
					getBean(beanName);
				}
			}
			// 非工廠bean
			else {
				// 獲取該Bean名稱對應的單例對象
				// getBean是BeanFactory接口定義的接口,是面向Spring內部和應用的接口
				// 其中包含了Bean的生命周期的部分
				// getBean非常重要,是觸發Bean的入口,也是獲取Bean工廠中已存在單例的手段
				getBean(beanName);
			}
		}
	}
	// Trigger post-initialization callback for all applicable beans...
	// 針對所有Bean觸發后置實例化回調,這里忽略
	for (String beanName : beanNames) {
		Object singletonInstance = getSingleton(beanName);
		if (singletonInstance instanceof SmartInitializingSingleton) {
			final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
			if (System.getSecurityManager() != null) {
				AccessController.doPrivileged(new PrivilegedAction<Object>() {
					@Override
					public Object run() {
						smartSingleton.afterSingletonsInstantiated();
						return null;
					}
				}, getAccessControlContext());
			}
			else {
				smartSingleton.afterSingletonsInstantiated();
			}
		}
	}
}

以上就是實例化Bean的觸發點,邏輯也是非常直觀,只要滿足非惰性單例的Bean才能進行實例化。其中分為兩種情形:

  • 工廠Bean,對於工廠Bean判斷是否為SmartFactoryBean,決定是否可以盡早實例化
  • 非工廠Bean

由於篇幅原因,關於isFactoryBean的實現這里不再詳細介紹,可以自行閱讀。接下來再繼續看getBean的實現。getBean是AbstractBeanFactory中的基礎實現:

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

其中內部調用doGetBean方法,方法參數較多:

  1. 第一個參數是Bean名稱
  2. 第二個參數是被要求的類型
  3. 第三個參數是創建單例時需要使用的構造參數
  4. 第三個參標志是否為只僅僅類型檢查獲取,而非實際使用

doGetBean是AbstractBeanFactory中實現獲取Bean的模板方法,作為BeanFactory的基礎實現類,子類可以擴展實現創建Bean的邏輯。其中實現以下模板步驟:

  1. 從單例緩存中獲取Bean
  2. 從父BeanFactory中獲取該Bean
  3. 先獲取該Bean的依賴Bean
  4. 按照不同的Bean作用域創建該Bean,該步驟被抽象為抽象接口,由子類實現擴展
  5. 如果該Bean是工廠Bean,則調用工廠Bean的生產方法getObject生成新的Bean
  6. 檢查類型是否匹配,如果不匹配,則進行類型轉換
protected <T> T doGetBean(
		final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly)
		throws BeansException {
	// 組裝bean名稱
	final String beanName = transformedBeanName(name);
	Object bean;
	// 檢查緩存,檢查是否已經過早實例化了該bean
	// Eagerly check singleton cache for manually registered singletons.
	Object sharedInstance = getSingleton(beanName);
	// 如果不為空,則表示已經過早的實例化了該bean
	if (sharedInstance != null && args == null) {
		// 日志打印
		if (logger.isDebugEnabled()) {
			// Spring中使用singletonsCurrentlyInCreation Set集合來存儲正在創建的單例Bean的名稱
			// 如果其中包含該beanName,則表示是循環引用
			if (isSingletonCurrentlyInCreation(beanName)) {
				logger.debug("Returning eagerly cached instance of singleton bean '" + beanName +
						"' that is not fully initialized yet - a consequence of a circular reference");
			}
			else {
				logger.debug("Returning cached instance of singleton bean '" + beanName + "'");
			}
		}
		// 如果該bean是工廠bean,則返回生產后的bean
		bean = 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);
		}
		// 	檢查是否有父BeanFactory
		// Check if bean definition exists in this factory.
		BeanFactory parentBeanFactory = getParentBeanFactory();
		// 如果父BeanFactory不為空,則該Bean的Bean定義被包含在BeanFactory中
		// 則使用父BeanFactory獲取該Bean,並返回創建的Bean
		// 這里實現了層次BeanFactory的能力,有點類似Java中的類加載器委托機制
		if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
			// Not found -> check parent.
			String nameToLookup = originalBeanName(name);
			if (args != null) {
				// Delegation to parent with explicit args.
				return (T) parentBeanFactory.getBean(nameToLookup, args);
			}
			else {
				// No args -> delegate to standard getBean method.
				return parentBeanFactory.getBean(nameToLookup, requiredType);
			}
		}
		// 如果父BeanFactory為空且非只僅僅類型檢查,則標記該Bean正在被創建
		if (!typeCheckOnly) {
			markBeanAsCreated(beanName);
		}
		try {
			// 獲取該Bean對應的RootBeanDefinition
			final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
			checkMergedBeanDefinition(mbd, beanName, args);
			// Guarantee initialization of beans that the current bean depends on.
			// 獲取該Bean依賴的Bean名稱
			String[] dependsOn = mbd.getDependsOn();
			// 遍歷獲取依賴的Bean
			// 實例化該bean前,先實例化其依賴的Bean
			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.
			// 這里只重點看單例Bean的創建過程,對於其他作用域類型,讀者自行閱讀
			// 這里就是模板方法的擴展點,createBean是定義的抽象接口,由子類擴展實現創建Bean的過程
			if (mbd.isSingleton()) {
				sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() {
					@Override
					public Object getObject() throws BeansException {
						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;
						}
					}
				});
				bean = 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);
				}
				bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
			}
			else {
				String scopeName = mbd.getScope();
				final 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, new ObjectFactory<Object>() {
						@Override
						public Object getObject() throws BeansException {
							beforePrototypeCreation(beanName);
							try {
								return createBean(beanName, mbd, args);
							}
							finally {
								afterPrototypeCreation(beanName);
							}
						}
					});
					bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
				}
				catch (IllegalStateException ex) {
					throw new BeanCreationException(beanName,
							"Scope '" + scopeName + "' is not active for the current thread; consider " +
							"defining a scoped proxy for this bean if you intend to refer to it from a singleton",
							ex);
				}
			}
		}
		catch (BeansException ex) {
			cleanupAfterBeanCreationFailure(beanName);
			throw ex;
		}
	}
	// 創建完Bean后,做類型檢查,是否與要求的類型匹配,如果不匹配,則進行類型轉換並返回
	// Check if required type matches the type of the actual bean instance.
	if (requiredType != null && bean != null && !requiredType.isInstance(bean)) {
		try {
			return getTypeConverter().convertIfNecessary(bean, requiredType);
		}
		catch (TypeMismatchException ex) {
			if (logger.isDebugEnabled()) {
				logger.debug("Failed to convert bean '" + name + "' to required type '" +
						ClassUtils.getQualifiedName(requiredType) + "'", ex);
			}
			throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
		}
	}
	return (T) bean;
}

這里有三點需要注意:

  • getSingleton,從單例緩存中獲取該Bean,因為由於循環關系可能會導致過早初始化該Bean
  • markBeanAsCreated,防止Bean重復創建,當Bean准備開始創建錢,需要記錄
  • getMergedLocalBeanDefinition,任何Bean都有可能存在父Bean,所以需要獲取合並的Bean定義,在Spring中創建Bean時,都會將Bean定義轉為RootBeanDefinition進行統一處理

createBean是子類的擴展實現Bean的創建過程,在Spring中默認由AbstractAutowireCapableBeanFactory中實現了Bean的實際創建:

@Override
protected Object createBean(String beanName, RootBeanDefinition mbd, Object[] args) throws BeanCreationException {
	if (logger.isDebugEnabled()) {
		logger.debug("Creating instance of bean '" + beanName + "'");
	}
	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.
	// 解析該Bean的Class類型
	Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
	// 如果該Bean沒有BeanClass,則設置。這里深度復制,不修改原有的Bean定義
	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 {
		// 給BeanPostProcessors返回目標Bean的代理對象
		// 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);
	}
	// 如果沒有代理對象,則這里創建該Bean
	Object beanInstance = doCreateBean(beanName, mbdToUse, args);
	if (logger.isDebugEnabled()) {
		logger.debug("Finished creating instance of bean '" + beanName + "'");
	}
	return beanInstance;
}

這里主要邏輯是:在實例化Bean錢確保解析Bean Class,在實例化之前增加擴展點,最后調用實際的創建Bean的邏輯。

關於實例化之前的擴張點,這里不再詳述,后續再介紹AOP的篇幅中再詳述描述。讀者也可以自行閱讀InstantiationAwareBeanPostProcessor的抽象。

接下來再繼續閱讀創建Bean的細節doCreateBean:

protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args)
		throws BeanCreationException {
	// Instantiate the bean.
	// 實例化的Bean的包裝器
	BeanWrapper instanceWrapper = null;
	if (mbd.isSingleton()) {
		instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
	}
	// 如果實例化的Bean的包裝器是空,則創建Bean
	if (instanceWrapper == null) {
		instanceWrapper = createBeanInstance(beanName, mbd, args);
	}
	// 獲取實例化的Bean
	final Object bean = (instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null);
	Class<?> beanType = (instanceWrapper != null ? instanceWrapper.getWrappedClass() : null);
	mbd.resolvedTargetType = beanType;
	// 后置處理修改合並的RootBeanDefinition,筆者也沒遇到過這種情形,這里忽略
	// 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;
		}
	}
	// 盡早緩存該Bean,以便后續循環引用時可以正常解析(循環引用時,直接從緩存中獲取即可,不會再重新創建Bean)
	// 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.isDebugEnabled()) {
			logger.debug("Eagerly caching bean '" + beanName +
					"' to allow for resolving potential circular references");
		}
		addSingletonFactory(beanName, new ObjectFactory<Object>() {
			@Override
			public Object getObject() throws BeansException {
				return getEarlyBeanReference(beanName, mbd, bean);
			}
		});
	}
	
	... 省略部分是Bean裝配和初始化的邏輯

	// 返回創建的Bean
	return exposedObject;
}

這里需要重點關注的是盡早緩存該Bean實例,主要是為了解決循環引用的問題。在下節Bean的裝配中,再回到這里重點介紹。

前文中介紹到CreateBean是由子類擴展實現相應的實例化Bean的邏輯,在Spring中,這里使用回調的方式,再回到回調的點細看getSingleton方法的實現:

// 該方法是由單例注冊器DefaultSingletonBeanRegistry實現,它具有緩存單例的能力
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
	Assert.notNull(beanName, "'beanName' must not be null");
	// 同步singletonObjects,保證線程安全,數據一致
	// singletonObjects存儲Spring容器中的所有單例Bean
	synchronized (this.singletonObjects) {
		// 首先從單例容器中獲取該單例
		Object singletonObject = this.singletonObjects.get(beanName);
		// 如果單例不存在,則創建該單例Bean
		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 + "'");
			}
			// 這里是一個擴展點,用於在創鍵單例錢進行回調
			// 默認實現中是判斷該單例是否正在創建,防重創建,其中使用Set保證唯一
			beforeSingletonCreation(beanName);
			// 創鍵是否為新的單例標志
			boolean newSingleton = false;
			boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
			if (recordSuppressedExceptions) {
				this.suppressedExceptions = new LinkedHashSet<Exception>();
			}
			// 這里回調對象工廠創建單例,調用將回到CreateBean那里
			// 並更新為新的單例的表示
			try {
				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 != NULL_OBJECT ? singletonObject : null);
	}
}

比較這里的單例容器和之前提到的盡早緩存單例的容器:

1.創建單例完成,將單例存入單例容器中

protected void addSingleton(String beanName, Object singletonObject) {
	// 同步單例容器singletonObjects
	synchronized (this.singletonObjects) {
		// 存入單例,使用映射表 beanName -> singletonObject
		this.singletonObjects.put(beanName, (singletonObject != null ? singletonObject : NULL_OBJECT));
		// 單例已經創建完成,則清理之前的盡早緩存的單例工廠對象
		this.singletonFactories.remove(beanName);
		// 清理過早緩存的該單例對象
		this.earlySingletonObjects.remove(beanName);
		// 在已經注冊的單例中,注冊上該單例名稱,表示該單例已經注冊
		this.registeredSingletons.add(beanName);
	}
}

2.過早緩存單例,解決循環引用

// 如果是單例,且Spring容器允許循環引用,該bean當前正在被創建
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
		isSingletonCurrentlyInCreation(beanName));
// 如果允許過早暴露單例
if (earlySingletonExposure) {
	if (logger.isDebugEnabled()) {
		logger.debug("Eagerly caching bean '" + beanName +
				"' to allow for resolving potential circular references");
	}
	// 將單例的對象工廠緩存
	addSingletonFactory(beanName, new ObjectFactory<Object>() {
		@Override
		public Object getObject() throws BeansException {
			return getEarlyBeanReference(beanName, mbd, bean);
		}
	});
}


protected void addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory) {
	Assert.notNull(singletonFactory, "Singleton factory must not be null");
	// 同步singletonObjects
	synchronized (this.singletonObjects) {
		// 如果singletonObjects中不包含該單例,則過早緩存
		if (!this.singletonObjects.containsKey(beanName)) {
			// 緩存創建這個bean對象的工廠
			this.singletonFactories.put(beanName, singletonFactory);
			// 從過早緩存容器中移除該bean,下次過早引用該bean時,重新從上面緩存的工廠中重新獲取
			this.earlySingletonObjects.remove(beanName);
			// 將該bean注冊到單例中
			this.registeredSingletons.add(beanName);
		}
	}
}

// 過早獲取該bean的單例,這里主要是為了解決循環引用問題
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
	// 首先從singletonObjects中獲取,如果有直接返回
	Object singletonObject = this.singletonObjects.get(beanName);
	// 如果不存在,且正在創建中
	if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
		// 同步singletonObjects
		synchronized (this.singletonObjects) {
			// 從過早緩存的容器中獲取
			singletonObject = this.earlySingletonObjects.get(beanName);
			// 如果過早緩存的容器中也沒有且支持過早引用
			if (singletonObject == null && allowEarlyReference) {
				// 獲取上述中提到的過早緩存的工廠
				ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
				// 緩存工廠不為空
				if (singletonFactory != null) {
					// 獲取該對象,將會調用getEarlyBeanReference方法
					singletonObject = singletonFactory.getObject();
					// 將其緩存到過早緩存中,避免下次再使用工廠獲取
					this.earlySingletonObjects.put(beanName, singletonObject);
					// 將該工廠存緩存中移除
					this.singletonFactories.remove(beanName);
				}
			}
		}
	}
	// 返回該對象
	return (singletonObject != NULL_OBJECT ? singletonObject : null);
}

Spring處理循環引用的方式非常巧妙,為了幫助理解,筆者這里整理了下流程圖幫助理解:

到這里Bean的創鍵基本上完成,后續就是依賴注入,將Bean裝配起來。

Bean的裝配

什么是Bean的裝配,即自動解決Bean之間的相互引用,能夠將其各自Set進彼此之中。比如,BeanA引用了BeanB,則Spring能自動的將連個Bean都實例化,然后將BeanB Set至BeanA中,這就是依賴注入,自動裝配。

Bean的裝配發生在Bean的實例化之后,在Spring中由AbstractAutowireCapableBeanFactoryBean工廠完成。繼續閱讀源碼:

protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args)
			throws BeanCreationException {
		...省略,這部分是實例化邏輯,上節中已經詳解
		// Initialize the bean instance.
		Object exposedObject = bean;
		try {
			// 這里處理Bean的裝配
			populateBean(beanName, mbd, instanceWrapper);
			if (exposedObject != null) {
				這里處理Bean的初始化
				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);
			}
		}
		... 省略
		return exposedObject;
	}

Bean的裝配由populateBean中實現:

// 該實現中處理Spring中的Bean裝配
// 有按照名稱、按照類型兩種范式裝配
protected void populateBean(String beanName, RootBeanDefinition mbd, BeanWrapper bw) {
	// 獲取Bean定義的屬性值,Bean定義的屬性值代表着需要裝配的成員域
	PropertyValues pvs = mbd.getPropertyValues();
	// 如果是空實例,則跳過返回,不裝配
	if (bw == null) {
		if (!pvs.isEmpty()) {
			throw new BeanCreationException(
					mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
		}
		else {
			// Skip property population phase for null instance.
			return;
		}
	}
	// 這里是一個擴展點,用於實例化后的后置處理InstantiationAwareBeanPostProcessor
	// InstantiationAwareBeanPostProcessor是BeanPostProcessor的擴展實現,前文中也稍微提過
	// 對於后置處理返回false,表示不需要裝配,否則需要裝配
	// Give any InstantiationAwareBeanPostProcessors the opportunity to modify the
	// state of the bean before properties are set. This can be used, for example,
	// to support styles of field injection.
	boolean continueWithPropertyPopulation = true;
	if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
		for (BeanPostProcessor bp : getBeanPostProcessors()) {
			if (bp instanceof InstantiationAwareBeanPostProcessor) {
				InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
				if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
					continueWithPropertyPopulation = false;
					break;
				}
			}
		}
	}
	// 如果不需要按照屬性裝配,則直接返回
	if (!continueWithPropertyPopulation) {
		return;
	}
	// 獲取Bean定義中的裝配模式
	if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME ||
			mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
		// 重新copy一份屬性值
		MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
		// 按照名稱進行屬性裝配
		// Add property values based on autowire by name if applicable.
		if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME) {
			autowireByName(beanName, mbd, bw, newPvs);
		}
		// 按照類型進行屬性裝配
		// Add property values based on autowire by type if applicable.
		if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
			autowireByType(beanName, mbd, bw, newPvs);
		}
		pvs = newPvs;
	}

	// 同樣是InstantiationAwareBeanPostProcessor后置處理屬性值的擴展點
	boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
	boolean needsDepCheck = (mbd.getDependencyCheck() != RootBeanDefinition.DEPENDENCY_CHECK_NONE);
	if (hasInstAwareBpps || needsDepCheck) {
		PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
		if (hasInstAwareBpps) {
			for (BeanPostProcessor bp : getBeanPostProcessors()) {
				if (bp instanceof InstantiationAwareBeanPostProcessor) {
					InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
					pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
					if (pvs == null) {
						return;
					}
				}
			}
		}
		if (needsDepCheck) {
			checkDependencies(beanName, mbd, filteredPds, pvs);
		}
	}
	// 應用屬性值到Bean中
	applyPropertyValues(beanName, mbd, bw, pvs);
}

其中非常重要的三個邏輯是:

  1. 按照名稱進行屬性裝配
  2. 按照類型進行屬性裝配
  3. 應用屬性值到Bean中

其次是InstantiationAwareBeanPostProcessor擴展點,它提供了實例化前后的擴展。
實例化前可以擴展實現自定義的實例化Bean邏輯;實例化后擴展可以實現自定義的裝配方式。同時也提供了后置處理即將被工廠應用到Bean的屬性值的擴展點。這里由於篇幅不再詳述,同樣在后續AOP章節中講解。

這里圍繞按照類型進行屬性裝配和應用屬性值到Bean中做詳細講解。其中關於如何配置裝配方式,這里不再贅述,可以翻閱文檔。

Notes:
需要注意以上的實現中由重新復制MutablePropertyValues的操作,因為在按名稱和按類型進行裝配的過程中,會修改Bean定義的屬性,故這里將其沖洗copy一份用於修改:將裝配的值解析后,覆蓋寫入Bean定義屬性中。

// 完成按照類型裝配Bean
// 第一個參數是Bean名稱、第二個參數是該Bean對應的Bean定義,第三個參數是該bean的包裝對象,第四個參數是該Bean的屬性值描述
protected void autowireByType(
		String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {
	// 獲取BeanFactory中配置的自定義類型轉換器,如果未配置,則使用BeanWrapper
	TypeConverter converter = getCustomTypeConverter();
	if (converter == null) {
		converter = bw;
	}
	// 指定大小,創建需要自動裝配的Bean名稱
	Set<String> autowiredBeanNames = new LinkedHashSet<String>(4);
	// 從Bean的屬性描述pvs中篩選出非簡單的滿足裝配的屬性名稱
	String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);
	// 遍歷需要裝配的屬性名稱
	for (String propertyName : propertyNames) {
		try {
			// 這里使用javabeans技術,獲取屬性描述器
			PropertyDescriptor pd = bw.getPropertyDescriptor(propertyName);
			// 如果裝配的類型是Object類型,則沒有任何意義,無法裝配,直接迭代下一個
			// Don't try autowiring by type for type Object: never makes sense,
			// even if it technically is a unsatisfied, non-simple property.
			// 非Object類型
			if (Object.class != pd.getPropertyType()) {
				// 獲取該成員屬性的方法參數
				MethodParameter methodParam = BeanUtils.getWriteMethodParameter(pd);
				// Do not allow eager init for type matching in case of a prioritized post-processor.
				boolean eager = !PriorityOrdered.class.isAssignableFrom(bw.getWrappedClass());
				DependencyDescriptor desc = new AutowireByTypeDependencyDescriptor(methodParam, eager);
				// 這里解析該屬性成員,這里會從BeanFactory中尋找該屬性的候選者,找到后,再進行實例化。返回屬性對應的Bean
				// 如A -> B,正在解析B,則這里將返回B
				Object autowiredArgument = resolveDependency(desc, beanName, autowiredBeanNames, converter);
				// 將屬性和候選者添加到屬性值中
				if (autowiredArgument != null) {
					pvs.add(propertyName, autowiredArgument);
				}
				// 注冊依賴關系,正向依賴和反向依賴
				for (String autowiredBeanName : autowiredBeanNames) {
					registerDependentBean(autowiredBeanName, beanName);
					if (logger.isDebugEnabled()) {
						logger.debug("Autowiring by type from bean name '" + beanName + "' via property '" +
								propertyName + "' to bean named '" + autowiredBeanName + "'");
					}
				}
				// 清理autowiredBeanNames,繼續下一個迭代
				autowiredBeanNames.clear();
			}
		}
		catch (BeansException ex) {
			throw new UnsatisfiedDependencyException(mbd.getResourceDescription(), beanName, propertyName, ex);
		}
	}
}

這里的邏輯和后續解析依賴的邏輯比較復雜,這里通過舉例幫助理解。

假如:Bean A持有成員域B。配置如下:

public class A {

	private B b;
}


<bean id="a" class=".....A" autowire="byType">
</bean>

<bean id="b" class=".....B" autowire-candidate="true">
</bean>

A自動裝配方式按照類型裝配,當a實例化后,在裝配時,需要對b成員進行填充。那么unsatisfiedNonSimpleProperties方法返回的屬性數組中將會包含"b"。

// 獲取Bean的不滿足非簡單的屬性
// 這里主要使用的是javabeans的自省技術,如果對這里感興趣可以參考oracle java中的javabeans技術
protected String[] unsatisfiedNonSimpleProperties(AbstractBeanDefinition mbd, BeanWrapper bw) {
	// 
	Set<String> result = new TreeSet<String>();
	// 獲取bean定義中的屬性值
	PropertyValues pvs = mbd.getPropertyValues();
	// 獲取該Bean實例中所有屬性描述器
	PropertyDescriptor[] pds = bw.getPropertyDescriptors();
	// 遍歷屬性描述器
	for (PropertyDescriptor pd : pds) {
		// 屬性描述器有寫方法,且該屬性沒有被排除依賴,且bean定義的屬性中不包含該屬性,且非簡單屬性,則認為需要自動裝配
		if (pd.getWriteMethod() != null && !isExcludedFromDependencyCheck(pd) && !pvs.contains(pd.getName()) &&
				!BeanUtils.isSimpleProperty(pd.getPropertyType())) {
			result.add(pd.getName());
		}
	}
	return StringUtils.toStringArray(result);
}

以上的b屬性是滿足,首先通過PropertyDescriptor[] pds = bw.getPropertyDescriptors()能獲取到屬性b的描述,然后b又未被排除依賴,在a的bean定義配置中也未配置b,且b是非簡單屬性。在Spring中認為這些屬性是簡單屬性:

public static boolean isSimpleValueType(Class<?> clazz) {
	return (ClassUtils.isPrimitiveOrWrapper(clazz) ||
			Enum.class.isAssignableFrom(clazz) ||
			CharSequence.class.isAssignableFrom(clazz) ||
			Number.class.isAssignableFrom(clazz) ||
			Date.class.isAssignableFrom(clazz) ||
			URI.class == clazz || URL.class == clazz ||
			Locale.class == clazz || Class.class == clazz);
}

且如果是以上這些類型的元素數組類型,也被認為是簡單類型。故b是需要被自動裝配。

后續便是從BeanFactory的Bean定義中尋找b的候選者:

@Override
public Object resolveDependency(DependencyDescriptor descriptor, String requestingBeanName,
		Set<String> autowiredBeanNames, TypeConverter typeConverter) throws BeansException {
	// 以下javaxInjectProviderClass、javaUtilOptionalClass、ObjectFactory、ObjectProvider這些都是特殊類型
	// 這里不做講解
	descriptor.initParameterNameDiscovery(getParameterNameDiscoverer());
	if (javaUtilOptionalClass == descriptor.getDependencyType()) {
		return new OptionalDependencyFactory().createOptionalDependency(descriptor, requestingBeanName);
	}
	else if (ObjectFactory.class == descriptor.getDependencyType() ||
			ObjectProvider.class == descriptor.getDependencyType()) {
		return new DependencyObjectProvider(descriptor, requestingBeanName);
	}
	else if (javaxInjectProviderClass == descriptor.getDependencyType()) {
		return new Jsr330ProviderFactory().createDependencyProvider(descriptor, requestingBeanName);
	}
	else {
		// 應用配置的Bean大多數進入該分支
		// 對實際依賴的惰性對象構造一個代理作為需要被裝配成員實例
		Object result = getAutowireCandidateResolver().getLazyResolutionProxyIfNecessary(
				descriptor, requestingBeanName);
		// 如果為空,則解析依賴
		if (result == null) {
			result = doResolveDependency(descriptor, requestingBeanName, autowiredBeanNames, typeConverter);
		}
		return result;
	}
}

顯然解析a對b的依賴,會進入最后一條分支,descriptor是b的屬性描述器,requestingBeanName是a,autowiredBeanNames是包含"b",類型轉換器是a實例的Bean包裝器。

// 這里邏輯非常復雜,只重點關注核心邏輯
public Object doResolveDependency(DependencyDescriptor descriptor, String beanName,
		Set<String> autowiredBeanNames, TypeConverter typeConverter) throws BeansException {
	InjectionPoint previousInjectionPoint = ConstructorResolver.setCurrentInjectionPoint(descriptor);
	try {
		Object shortcut = descriptor.resolveShortcut(this);
		if (shortcut != null) {
			return shortcut;
		}
		// 根據屬性描述器獲取依賴對象的類型
		Class<?> type = descriptor.getDependencyType();
		Object value = getAutowireCandidateResolver().getSuggestedValue(descriptor);
		if (value != null) {
			if (value instanceof String) {
				String strVal = resolveEmbeddedValue((String) value);
				BeanDefinition bd = (beanName != null && containsBean(beanName) ? getMergedBeanDefinition(beanName) : null);
				value = evaluateBeanDefinitionString(strVal, bd);
			}
			TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter());
			return (descriptor.getField() != null ?
					converter.convertIfNecessary(value, type, descriptor.getField()) :
					converter.convertIfNecessary(value, type, descriptor.getMethodParameter()));
		}
		Object multipleBeans = resolveMultipleBeans(descriptor, beanName, autowiredBeanNames, typeConverter);
		if (multipleBeans != null) {
			return multipleBeans;
		}
		// 按照類型尋找bean候選者的bean名稱
		Map<String, Object> matchingBeans = findAutowireCandidates(beanName, type, descriptor);
		if (matchingBeans.isEmpty()) {
			if (isRequired(descriptor)) {
				raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);
			}
			return null;
		}

		// 決定候選者中的一個成為被裝配的Bean
		String autowiredBeanName;
		Object instanceCandidate;
		if (matchingBeans.size() > 1) {
			autowiredBeanName = determineAutowireCandidate(matchingBeans, descriptor);
			if (autowiredBeanName == null) {
				if (isRequired(descriptor) || !indicatesMultipleBeans(type)) {
					return descriptor.resolveNotUnique(type, matchingBeans);
				}
				else {
					// In case of an optional Collection/Map, silently ignore a non-unique case:
					// possibly it was meant to be an empty collection of multiple regular beans
					// (before 4.3 in particular when we didn't even look for collection beans).
					return null;
				}
			}
			instanceCandidate = matchingBeans.get(autowiredBeanName);
		}
		else {
			// We have exactly one match.
			Map.Entry<String, Object> entry = matchingBeans.entrySet().iterator().next();
			autowiredBeanName = entry.getKey();
			instanceCandidate = entry.getValue();
		}
		if (autowiredBeanNames != null) {
			autowiredBeanNames.add(autowiredBeanName);
		}
		// 實例化被裝配的Bean並返回
		return (instanceCandidate instanceof Class ?
				descriptor.resolveCandidate(autowiredBeanName, type, this) : instanceCandidate);
	}
	finally {
		ConstructorResolver.setCurrentInjectionPoint(previousInjectionPoint);
	}
}

當按照類型B從BeanFactory中尋找后選擇時,會尋找到"b"的bean名稱,后續在實例化時,將實例化b配置的Bean。

其中descriptor.resolveCandidate實例化需要重點關注:

// 是不是很熟悉,又是調用BeanFactory的getBean,這是BeanFactory的基本能力
// 當解析依賴的時候,這里是間接遞歸調用
public Object resolveCandidate(String beanName, Class<?> requiredType, BeanFactory beanFactory)
		throws BeansException {
	return beanFactory.getBean(beanName, requiredType);
}

當解析依賴的時候,將會間接遞歸調用getBean方法。這里將會getBean("b", .....B)。

當解析到被裝配的Bean后,就會加入至屬性映射pvs中。最后再調用applyPropertyValues將屬性填入。這里即將b填充至a中。

protected void applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs) {
	// 如果沒有屬性,則直接返回,無可應用
	if (pvs == null || pvs.isEmpty()) {
		return;
	}
	if (System.getSecurityManager() != null && bw instanceof BeanWrapperImpl) {
		((BeanWrapperImpl) bw).setSecurityContext(getAccessControlContext());
	}
	MutablePropertyValues mpvs = null;
	List<PropertyValue> original;
	// 如果MutablePropertyValues是已經被轉換,則直接短路填充
	if (pvs instanceof MutablePropertyValues) {
		mpvs = (MutablePropertyValues) pvs;
		if (mpvs.isConverted()) {
			// Shortcut: use the pre-converted values as-is.
			try {
				bw.setPropertyValues(mpvs);
				return;
			}
			catch (BeansException ex) {
				throw new BeanCreationException(
						mbd.getResourceDescription(), beanName, "Error setting property values", ex);
			}
		}
		original = mpvs.getPropertyValueList();
	}
	else {
		original = Arrays.asList(pvs.getPropertyValues());
	}
	// 否則獲取自定義轉換器
	TypeConverter converter = getCustomTypeConverter();
	if (converter == null) {
		converter = bw;
	}
	// 構建Bean定義值解析器
	BeanDefinitionValueResolver valueResolver = new BeanDefinitionValueResolver(this, beanName, mbd, converter);
	// Create a deep copy, resolving any references for values.
	List<PropertyValue> deepCopy = new ArrayList<PropertyValue>(original.size());
	boolean resolveNecessary = false;
	// 遍歷屬性值
	for (PropertyValue pv : original) {
		// 如果屬性值已經被轉換,直接加入到列表中
		if (pv.isConverted()) {
			deepCopy.add(pv);
		}
		else {
			// 獲取屬性名,屬性值
			String propertyName = pv.getName();
			Object originalValue = pv.getValue();
			// 解析屬性值
			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);
			}
			// 避免重新裝換,存入到合並的bean定義中
			// Possibly store converted value in merged bean definition,
			// in order to avoid re-conversion for every created bean instance.
			if (resolvedValue == originalValue) {
				if (convertible) {
					pv.setConvertedValue(convertedValue);
				}
				deepCopy.add(pv);
			}
			else if (convertible && originalValue instanceof TypedStringValue &&
					!((TypedStringValue) originalValue).isDynamic() &&
					!(convertedValue instanceof Collection || ObjectUtils.isArray(convertedValue))) {
				pv.setConvertedValue(convertedValue);
				deepCopy.add(pv);
			}
			else {
				resolveNecessary = true;
				deepCopy.add(new PropertyValue(pv, convertedValue));
			}
		}
	}
	if (mpvs != null && !resolveNecessary) {
		mpvs.setConverted();
	}
	// 填充屬性值
	// Set our (possibly massaged) deep copy.
	try {
		bw.setPropertyValues(new MutablePropertyValues(deepCopy));
	}
	catch (BeansException ex) {
		throw new BeanCreationException(
				mbd.getResourceDescription(), beanName, "Error setting property values", ex);
	}
}

這里需要關注的是resolveValueIfNecessary方法。當未按照類型和名稱進行自動裝配時,BeanDefinitionValueResolver幫助類將會解析被包含在Bean定義中的值為實際的Bean並且將其填充到目標Bean實例中,

上述的Notes中提到有MutablePropertyValues重新copy,然后將解析的依賴值覆蓋寫入到屬性中,這里resolveValueIfNecessary中將會抉擇Bean定義屬性值的類型,如果是實際待裝配填充的值,則不做任何處理;否則將會根據Bean定義屬性的值類型,做相應處理,具體細節這里不再贅述。

Bean的后置處理

在Bean裝配完畢后,這個Bean就已經初具形態,基本上是一個完整的Bean。因為對象就是成員與行為的集合,裝配即補齊其依賴的成員。這是便可以執行Bean的初始化了,但是Spring提供了擴展點,在初始化前后都為應用預留了擴張點。

上篇文章中介紹到BeanPostProcessor的容器擴展點,只是講解了Spring上下文如何實例化和注冊BeanPostProcessor,單對於BeanPostProcessor的喚醒調用沒有提及,這里有了Bean創建的基礎,再來看該問題。

繼續源碼分析,在裝配完成后,開始初始化:

protected Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd) {
	// 由於部分對象可能會有訪問安全控制,所以需要做權限訪問
	// 在初始化和后置處理前,需要處理Spring中的另一個擴展點Aware接口
	if (System.getSecurityManager() != null) {
		AccessController.doPrivileged(new PrivilegedAction<Object>() {
			@Override
			public Object run() {
				// 帶有權限控制,喚醒Aware接口,注入相應的Bean
				invokeAwareMethods(beanName, bean);
				return null;
			}
		}, getAccessControlContext());
	}
	else {
		// 喚醒Aware接口,注入相應的Bean
		invokeAwareMethods(beanName, bean);
	}
	// 初始化前的后置處理,喚醒BeanPostProcessor的applyBeanPostProcessorsBeforeInitialization
	Object wrappedBean = bean;
	if (mbd == null || !mbd.isSynthetic()) {
		wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
	}
	try {
		// 喚醒初始化方法,初始化Bean
		invokeInitMethods(beanName, wrappedBean, mbd);
	}
	catch (Throwable ex) {
		throw new BeanCreationException(
				(mbd != null ? mbd.getResourceDescription() : null),
				beanName, "Invocation of init method failed", ex);
	}
	// 初始化完成后的后置處理,喚醒BeanPostProcessor的applyBeanPostProcessorsAfterInitialization
	if (mbd == null || !mbd.isSynthetic()) {
		wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
	}
	return wrappedBean;
}

這里重點看前后的后置處理,至於Aware接口的處理和初始化的執行,下節再詳細分析。

1.初始化前的后置處理

@Override
public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
		throws BeansException {
	// 遍歷調用BeanFactory中的BeanPostProcessor,然后后置處理該Bean
	Object result = existingBean;
	for (BeanPostProcessor processor : getBeanPostProcessors()) {
		result = processor.postProcessBeforeInitialization(result, beanName);
		if (result == null) {
			return result;
		}
	}
	// 返回結果
	return result;
}

2.初始化后的后置處理

@Override
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
		throws BeansException {
	// 遍歷調用BeanFactory中的BeanPostProcessor后置處理初始化后的Bean
	Object result = existingBean;
	for (BeanPostProcessor processor : getBeanPostProcessors()) {
		result = processor.postProcessAfterInitialization(result, beanName);
		if (result == null) {
			return result;
		}
	}
	// 返回處理后的結果
	return result;
}

Bean的初始化

上節Bean的后置處理中已經初步提及到初始化的過程:

  1. 處理Spring的Aware系列接口
  2. 初始化前的后置處理
  3. 喚醒Bean的初始化
  4. 初始化后的后置處理

1.處理Aware接口

private void invokeAwareMethods(final String beanName, final Object bean) {
	// 首先如果該Bean是Aware實例
	if (bean instanceof Aware) {
		// 如果該bean是BeanNameAware實例
		if (bean instanceof BeanNameAware) {
			// 則將該Beand的beanName set進該Bean中
			((BeanNameAware) bean).setBeanName(beanName);
		}
		// 如果該Bean是BeanClassLoaderAware實例
		if (bean instanceof BeanClassLoaderAware) {
			// 則將加載該Bean的類加載器set進該beanzhong 
			((BeanClassLoaderAware) bean).setBeanClassLoader(getBeanClassLoader());
		}
		// 如果該Bean是BeanFactoryAware的實例
		if (bean instanceof BeanFactoryAware) {
			// 則將BeanFactory set進該Bean中
			((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
		}
	}
}

這里只處理BeanNameAware、BeanClassLoaderAware和BeanFactoryAware三個Aware接口。但是在Spring中還有很多Aware接口,如:

  • 經常使用的ApplicationContextAware接口
  • ResourceLoaderAware接口
  • MessageSourceAware接口
  • EnvironmentAware接口

等等,它們是在何處處理的?Spring中針對這些接口使用了BeanPostProcessor的方式注入相應的Bean。

以上的這些Aware接口要求注入分別是ApplicationContext,ResourceLoader,MessageSource,Environment。

但是這些都是更偏上層應用,BeanFactory屬於更底層的基礎組件,所以不可能依賴倒轉,在BeanFactory中處理這些Aware接口,將處理這些Aware接口的依賴注入。這樣勢必會造成BeanFactory依賴反轉,與上層的這些接口耦合,那樣違背設計。

同時需要注意到的是,ApplicationContext,ResourceLoader,MessageSource,Environment這些組件都是可以通過ApplicationContext一致對外提供接口,所以只要向實現這些接口的Bean中注入ApplicationContext即可。

Spring中使用ApplicationContextAwareProcessor的BeanPostProcessor后置處理,完成ApplicationContext注入到實現以上接口的Bean中:

@Override
public Object postProcessBeforeInitialization(final Object bean, String beanName) throws BeansException {
	// 后置處理注入ApplicationContext至實現了Aware接口中
	// 區分訪問安全權限
	AccessControlContext acc = null;
	if (System.getSecurityManager() != null &&
			(bean instanceof EnvironmentAware || bean instanceof EmbeddedValueResolverAware ||
					bean instanceof ResourceLoaderAware || bean instanceof ApplicationEventPublisherAware ||
					bean instanceof MessageSourceAware || bean instanceof ApplicationContextAware)) {
		acc = this.applicationContext.getBeanFactory().getAccessControlContext();
	}
	if (acc != null) {
		AccessController.doPrivileged(new PrivilegedAction<Object>() {
			@Override
			public Object run() {
				invokeAwareInterfaces(bean);
				return null;
			}
		}, acc);
	}
	else {
		invokeAwareInterfaces(bean);
	}
	// 返回Bean,Spring需要處理返回結果,將其注冊到單例容器中
	return bean;
}

// 喚醒Aware接口處理,這里處理邏輯與之前的處理Aware接口基本類似
private void invokeAwareInterfaces(Object bean) {
	// 如果該Bean是Aware接口實例,則再按照不同的具體的接口,注入相應的對象進入該Bean
	if (bean instanceof Aware) {
		// 如果是EnvironmentAware實例,注入Environment
		if (bean instanceof EnvironmentAware) {
			((EnvironmentAware) bean).setEnvironment(this.applicationContext.getEnvironment());
		}
		// 如果是EmbeddedValueResolverAware實例,注入解析器
		if (bean instanceof EmbeddedValueResolverAware) {
			((EmbeddedValueResolverAware) bean).setEmbeddedValueResolver(this.embeddedValueResolver);
		}
		// 如果是ResourceLoaderAware實例,注入上下文
		if (bean instanceof ResourceLoaderAware) {
			((ResourceLoaderAware) bean).setResourceLoader(this.applicationContext);
		}
		// 如果是ApplicationEventPublisherAware實例,注入上下文
		if (bean instanceof ApplicationEventPublisherAware) {
			((ApplicationEventPublisherAware) bean).setApplicationEventPublisher(this.applicationContext);
		}
		// 如果是EmbeddedValueResolverAware實例,注入上下文
		if (bean instanceof MessageSourceAware) {
			((MessageSourceAware) bean).setMessageSource(this.applicationContext);
		}
		// 如果是ApplicationContextAware實例,注入上下文
		if (bean instanceof ApplicationContextAware) {
			((ApplicationContextAware) bean).setApplicationContext(this.applicationContext);
		}
	}
}

在處理完Aware接口后,就是Bean的初始化。但是Spring針對初始化做了增強處理,能夠支持多種形態的初始化方式:

  • 實現了InitializingBean的方式
  • 自定義指定init-method方式
  • j2EE中定義的@PostConstruct初始化方式

下面就讓我們逐個進行分析

// 該方法主要是針對Bean進行初始化
protected void invokeInitMethods(String beanName, final Object bean, RootBeanDefinition mbd)
		throws Throwable {
	// 判斷該Bean是否為InitializingBean實例
	boolean isInitializingBean = (bean instanceof InitializingBean);
	// 如果是InitializingBean實例且afterPropertiesSet方法不是額外的管理初始化方法
	// 則調用afterPropertiesSet方法執行Bean的初始化邏輯
	if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {
		if (logger.isDebugEnabled()) {
			logger.debug("Invoking afterPropertiesSet() on bean with name '" + beanName + "'");
		}
		if (System.getSecurityManager() != null) {
			try {
				AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
					@Override
					public Object run() throws Exception {
						((InitializingBean) bean).afterPropertiesSet();
						return null;
					}
				}, getAccessControlContext());
			}
			catch (PrivilegedActionException pae) {
				throw pae.getException();
			}
		}
		else {
			((InitializingBean) bean).afterPropertiesSet();
		}
	}
	// 如果bean定義不為空
	if (mbd != null) {
		// 獲取Bean定義的初始化方法
		String initMethodName = mbd.getInitMethodName();
		// 如果初始化方法不為空,且不是isInitializingBean和afterPropertiesSet方法,則執行自定義的初始化方法
		if (initMethodName != null && !(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
				!mbd.isExternallyManagedInitMethod(initMethodName)) {
			invokeCustomInitMethod(beanName, bean, mbd);
		}
	}
}

初始化中分為兩種情況,一種是實現InitializingBean,另一種是非實現的InitializingBean。前者執行afterPropertiesSet初始化,后者執行自定義配置的initMethod進行初始化。

總結

至此Spring的Bean生命周期的大部分就講完了,主要過程就是:

  • 實例化Bean
  • 實例化的后置處理
  • 裝配Bean
  • 執行Aware接口處理
  • 初始化前的后置處理
  • 初始化Bean
  • 初始化后的后置處理
  • Bean使用階段
  • 執行DisposableBean銷毀Bean
  • 執行自定義銷毀方法
  • 被GC回收

同樣至此,Spring源碼系列的基於XML配置的IOC也結束了,后續Spring源碼分析將進入第二階段:基於注解配置的IOC源碼。

第三階段將是Spring框架的另一個模塊:Spring AOP的源碼解析。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM