spring源碼:bean的創建


從doGetBean()方法中可以知道,bean會根據不同的scope進行bean創建,但真實創建bean實例的是createBean()方法。下面我們就跟蹤一下這個方法:

createBean()源碼

AbstractAutowireCapableBeanFactory.java

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

		if (logger.isDebugEnabled()) {
			logger.debug("Creating instance of bean '" + beanName + "'");
		}
		RootBeanDefinition mbdToUse = mbd;

		//  確定並加載bean的class
		Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
		if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
			mbdToUse = new RootBeanDefinition(mbd);
			mbdToUse.setBeanClass(resolvedClass);
		}

		// 準備覆蓋的方法
		try {
			mbdToUse.prepareMethodOverrides();
		}
		catch ...
		try {
			// 給 Bean Post 處理器一個機會來返回代理而不是目標 Bean 實例。
			Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
			//應用初始化前的後處理器,如果處理器中返回了AOP的代理對象,則直接返回該單例對象,不需要繼續創建
			if (bean != null) {
				return bean;
			}
		}
		catch ....
		try {
			//創建bean對象
			Object beanInstance = doCreateBean(beanName, mbdToUse, args);

			if (logger.isDebugEnabled()) {
				logger.debug("Finished creating instance of bean '" + beanName + "'");
			}
			return beanInstance;
		}
		catch ...
		catch ...
		}
	}

上面代碼對應步驟爲:

  1. 根據設置的class屬性或者根據className來解析到class
  2. 對override屬性進行標記和驗證(bean XML配置中的lookup-method和replace-method屬性)
  3. 應用初始化前的後處理器,如果處理器中返回了AOP的代理對象,則直接返回該單例對象,不需要繼續創建
  4. 創建bean
    從上面知道創建bean的代碼被封裝在doCreateBean()中。

doCreateBean()源碼

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

		// 1. 先從factoryBeanInstanceCache緩存中嘗試獲取
		BeanWrapper instanceWrapper = null;
		if (mbd.isSingleton()) {
			instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
		}
		// 2. 如果緩存中不存在,則根據bean對應的策略創建新的實例,如:工廠方法、構造器自動注入、簡單初始化
		if (instanceWrapper == null) {
			// ------------bean的實例化-------------------
			instanceWrapper = createBeanInstance(beanName, mbd, args);
		}
		final Object bean = instanceWrapper.getWrappedInstance();
		Class<?> beanType = instanceWrapper.getWrappedClass();
		if (beanType != NullBean.class) {
			mbd.resolvedTargetType = beanType;
		}

		// 3.  應用MergedBeanDefinitionPostProcessor 後處理器,合併bean的定義信息
		// Autowire等註解信息就是在這一步完成預解析,並且將註解需要的信息放入緩存
		synchronized (mbd.postProcessingLock) {
			if (!mbd.postProcessed) {
				try {
					applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
				}
				catch ...
				mbd.postProcessed = true;
			}
		}
		// 4. 依賴處理
		// 是否需要提前曝光 = 單例&允許循環依賴&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");
			}
			//爲了避免循環依賴,在bean初始化完成前,就將創建bean實例的ObjectFactory放入工廠緩存(singletonFactories)
			// AOP就是在這裏將advice動態織入到bean中
			addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
		}

		// 5. 對bean屬性進行填充,注入bean中的屬性,會遞歸初始化依賴的bean
		Object exposedObject = bean;
		try {
			//  ----------- 填充屬性 --------
			populateBean(beanName, mbd, instanceWrapper);
			//  --------------bean的初始化------------------
			//調用初始化方法,比如init-method、注入Aware對象、應用後處理器
			exposedObject = initializeBean(beanName, exposedObject, mbd);
		}
		catch ....
		// 6. 循環依賴檢查
		if (earlySingletonExposure) {
			//從提前曝光的bean緩存中查詢bean,目的是驗證是否有循環依賴存在
			//如果存在循環依賴,也就是說該bean已經被其他bean遞歸加載過,放入了提早曝光的bean緩存中
			Object earlySingletonReference = getSingleton(beanName, false);
			//只有檢測到循環依賴的情況下,earlySingletonReference纔不會爲null
			if (earlySingletonReference != null) {
				//如果exposedObject沒有在 initializeBean 初始化方法中改變,也就是沒有被增強
				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);
						}
					}
					//因爲bean創建後,其依賴的bean一定也是已經創建的
					//如果actualDependentBeans不爲空,則表示依賴的bean並沒有被創建完,即存在循環依賴
					if (!actualDependentBeans.isEmpty()) {
						throw new BeanCurrentlyInCreationException(beanName,...);
					}
				}
			}
		}

		// 7. 註冊DisposableBean,對應xml中的 destroy-method,以便的銷燬時調用
		try {
			registerDisposableBeanIfNecessary(beanName, bean, mbd);
		}
		catch ...

		return exposedObject;
	}

以上方法的步驟爲:

  1. 如果是單例則首先清除緩存
  2. 實例化bean,並使用BeanWarpper包裝
    1. 如果存在工廠方法,則使用工廠方法實例化
    2. 如果有多個構造函數,則根據傳入的參數確定構造函數進行初始化
    3. 使用默認的構造函數初始化
  3. 應用MergedBeanDefinitionPostProcessor,Autowired註解就是在這樣完成的解析工作
  4. 依賴處理。如果A和B存在循環依賴,那麼Spring在創建B的時候,需要自動注入A時,並不會直接創建再次創建A,而是通過放入緩存中A的ObjectFactory來創建實例,這樣就解決了循環依賴的問題
  5. 屬性填充。所有需要的屬性都在這一步注入到bean
  6. 循環依賴檢查
  7. 註冊DisposableBean。如果配置了destroy-method,這裏需要註冊,以便在銷燬時調用
  8. 完成創建並返回
    從上面的步驟可以知道bean的創建主要是三步:
    1. bean的實例化
    2. 實例化後bean屬性的填充
    3. bean的初始化

下面我們一個一個進行解析

1.bean的實例化

protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
		// 獲取bean class
		Class<?> beanClass = resolveBeanClass(mbd, beanName);

		if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) {
			throw new BeanCreationException(mbd.getResourceDescription(), beanName,
					"Bean class isn't public, and non-public access not allowed: " + beanClass.getName());
		}

		Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
		if (instanceSupplier != null) {
			return obtainFromSupplier(instanceSupplier, beanName);
		}
		// 如果工廠方法不爲空(RootBeanDefinition中存在factoryMethodNam屬性,或者配置文件中配置了factory-method),則使用工廠方法初始化策略
		if (mbd.getFactoryMethodName() != null)  {
			return instantiateUsingFactoryMethod(beanName, mbd, args);
		}

		// Shortcut when re-creating the same bean...
		boolean resolved = false;
		boolean autowireNecessary = false;
		if (args == null) {
			synchronized (mbd.constructorArgumentLock) {
				//如果一個類有多個構造函數,每個構造函數都有不同的參數,所以調用前需要先根據參數鎖定構造函數或對應的工廠方法
				if (mbd.resolvedConstructorOrFactoryMethod != null) {
					resolved = true;
					autowireNecessary = mbd.constructorArgumentsResolved;
				}
			}
		}
		//如果已經解析過則使用解析好的構造函數方法不需要再次鎖定
		if (resolved) {
			if (autowireNecessary) {
				//構造函數自動注入
				return autowireConstructor(beanName, mbd, null, null);
			}
			else {
				//使用默認構造函數構造
				return instantiateBean(beanName, mbd);
			}
		}

		// 根據參數解析構造函數
		Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
		if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
				mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args))  {
			//構造函數自動注入
			return autowireConstructor(beanName, mbd, ctors, args);
		}

		// 使用默認構造函數
		return instantiateBean(beanName, mbd);
	}

從上面的代碼發現實例化bean的方式就三種:

  1. 如果存在工廠方法,則使用工廠方法實例化
  2. 如果有多個構造函數,則根據傳入的參數確定構造函數進行初始化
  3. 使用默認的構造函數初始化
    主要涉及的方法:
    instantiateUsingFactoryMethod()、autowireConstructor()、instantiateBean()
autowireConstructor()方法

ConstructorResolver.java

public BeanWrapper autowireConstructor(String beanName, RootBeanDefinition mbd,
			@Nullable Constructor<?>[] chosenCtors, @Nullable Object[] explicitArgs) {

		BeanWrapperImpl bw = new BeanWrapperImpl();
		this.beanFactory.initBeanWrapper(bw);

		Constructor<?> constructorToUse = null;
		ArgumentsHolder argsHolderToUse = null;
		Object[] argsToUse = null;

		/**
		 *  1. 構造參數的確定
		 *		1.1 調用getBean方法時傳入
		 *		1.2 緩存中獲取
		 *		1.3 配置文件中獲取
		 */


		//explicitArgs通過getBean方法傳入
		//如果getBean方法調用的時候指定方法參數那麼直接使用
		if (explicitArgs != null) {
			argsToUse = explicitArgs;
		}
		else {
			//如果getBean方法沒有傳入參數,則嘗試從配置文件中解析
			Object[] argsToResolve = null;
			synchronized (mbd.constructorArgumentLock) {
				constructorToUse = (Constructor<?>) mbd.resolvedConstructorOrFactoryMethod;
				if (constructorToUse != null && mbd.constructorArgumentsResolved) {
					// 從緩存中獲取
					argsToUse = mbd.resolvedConstructorArguments;
					if (argsToUse == null) {
						//配置的構造函數參數
						argsToResolve = mbd.preparedConstructorArguments;
					}
				}
			}
			if (argsToResolve != null) {
				// 解析參數類型,如構造函數A(int,int)通過此方法後就會把配置中的("1","1")轉換成(1,1)
				//緩存中的值可能是原始值也可能是最終值
				argsToUse = resolvePreparedArguments(beanName, mbd, bw, constructorToUse, argsToResolve);
			}
		}

		//沒有被緩存
		if (constructorToUse == null) {
			// 需要解析構造函數。
			boolean autowiring = (chosenCtors != null ||
					mbd.getResolvedAutowireMode() == AutowireCapableBeanFactory.AUTOWIRE_CONSTRUCTOR);
			ConstructorArgumentValues resolvedValues = null;

			int minNrOfArgs;
			if (explicitArgs != null) {
				minNrOfArgs = explicitArgs.length;
			}
			else {
				//配置文件中配置的構造函數參數
				ConstructorArgumentValues cargs = mbd.getConstructorArgumentValues();
				//用於承載解析後的參數值
				resolvedValues = new ConstructorArgumentValues();
				//能解析到的參數個數
				minNrOfArgs = resolveConstructorArguments(beanName, mbd, bw, cargs, resolvedValues);
			}
			/**
			 *  2. 構造函數的確定
			 *
			 */
			// Take specified constructors, if any.
			Constructor<?>[] candidates = chosenCtors;
			if (candidates == null) {
				Class<?> beanClass = mbd.getBeanClass();
				try {
					candidates = (mbd.isNonPublicAccessAllowed() ?
							beanClass.getDeclaredConstructors() : beanClass.getConstructors());
				}
				catch ...
			}
			//構造函數排序,public構造函數優先參數數量降序、非public構造函數參數數量降序
			AutowireUtils.sortConstructors(candidates);
			int minTypeDiffWeight = Integer.MAX_VALUE;
			Set<Constructor<?>> ambiguousConstructors = null;
			LinkedList<UnsatisfiedDependencyException> causes = null;

			for (Constructor<?> candidate : candidates) {
				Class<?>[] paramTypes = candidate.getParameterTypes();

				if (constructorToUse != null && argsToUse.length > paramTypes.length) {
					// 如果已經找到選用的構造參數,而且傳入的參數個數大於當前的構造參數個數則終止,因爲構造函數已經按照參數個數降序排列
					break;
				}
				if (paramTypes.length < minNrOfArgs) {
					//參數個數不相等
					continue;
				}

				ArgumentsHolder argsHolder;
				if (resolvedValues != null) {
					try {
						//有參數,則根據參數類型和參數名構造對象

						//註釋上獲取參數名稱
						String[] paramNames = ConstructorPropertiesChecker.evaluate(candidate, paramTypes.length);
						if (paramNames == null) {
							//參數名稱探測器
							ParameterNameDiscoverer pnd = this.beanFactory.getParameterNameDiscoverer();
							if (pnd != null) {
								//獲取構造參數名稱
								paramNames = pnd.getParameterNames(candidate);
							}
						}
						///根據名稱和數據類型創建參數持有者
						argsHolder = createArgumentArray(beanName, mbd, resolvedValues, bw, paramTypes, paramNames,
								getUserDeclaredConstructor(candidate), autowiring);
					}
					catch...
				}
				else {
					// Explicit arguments given -> arguments length must match exactly.
					if (paramTypes.length != explicitArgs.length) {
						continue;
					}
					//構造函數沒有參數
					argsHolder = new ArgumentsHolder(explicitArgs);
				}

				//檢查是否有不確定性的構造函數存在,例如不同構造函數的參數爲父子關係
				int typeDiffWeight = (mbd.isLenientConstructorResolution() ?
						argsHolder.getTypeDifferenceWeight(paramTypes) : argsHolder.getAssignabilityWeight(paramTypes));
				// 如果它代表着當前最接近的匹配則選擇作爲構造函數
				if (typeDiffWeight < minTypeDiffWeight) {
					constructorToUse = candidate;
					argsHolderToUse = argsHolder;
					argsToUse = argsHolder.arguments;
					minTypeDiffWeight = typeDiffWeight;
					ambiguousConstructors = null;
				}
				else if (constructorToUse != null && typeDiffWeight == minTypeDiffWeight) {
					if (ambiguousConstructors == null) {
						ambiguousConstructors = new LinkedHashSet<>();
						ambiguousConstructors.add(constructorToUse);
					}
					ambiguousConstructors.add(candidate);
				}
			}

			if (constructorToUse == null) {
				if (causes != null) {
					UnsatisfiedDependencyException ex = causes.removeLast();
					for (Exception cause : causes) {
						this.beanFactory.onSuppressedException(cause);
					}
					throw ex;
				}
				throw new BeanCreationException(mbd.getResourceDescription(), beanName,..);
			}
			else if (ambiguousConstructors != null && !mbd.isLenientConstructorResolution()) {
				throw new BeanCreationException(mbd.getResourceDescription(), beanName,..);
			}

			if (explicitArgs == null) {
				//將解析的構造函數加入緩存
				argsHolderToUse.storeCache(mbd, constructorToUse);
			}
		}

		try {
			//使用策略的instantiate方法,實例化bean
			final InstantiationStrategy strategy = beanFactory.getInstantiationStrategy();
			Object beanInstance;

			if (System.getSecurityManager() != null) {
				final Constructor<?> ctorToUse = constructorToUse;
				final Object[] argumentsToUse = argsToUse;
				beanInstance = AccessController.doPrivileged((PrivilegedAction<Object>) () ->
						strategy.instantiate(mbd, beanName, beanFactory, ctorToUse, argumentsToUse),
						beanFactory.getAccessControlContext());
			}
			else {
				beanInstance = strategy.instantiate(mbd, beanName, this.beanFactory, constructorToUse, argsToUse);
			}

			//將構造的實例加入BeanWrapper中
			bw.setBeanInstance(beanInstance);
			return bw;
		}
		catch ...
	}

此方法的主要邏輯爲:

  1. 構造參數的確定
  2. 構造函數的確定
  3. 根據構造函數轉換傳入參數的類型
  4. 構造函數不確定性的驗證
  5. 根據實例化策略及確定的構造函數和參數實例化bean.
instantiateBean()無參構造
protected BeanWrapper instantiateBean(final String beanName, final RootBeanDefinition mbd) {
		try {
			Object beanInstance;
			final BeanFactory parent = this;
			if (System.getSecurityManager() != null) {
				beanInstance = AccessController.doPrivileged((PrivilegedAction<Object>) () ->
						getInstantiationStrategy().instantiate(mbd, beanName, parent),
						getAccessControlContext());
			}
			else {
				//實例化
				beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, parent);
			}
			BeanWrapper bw = new BeanWrapperImpl(beanInstance);
			initBeanWrapper(bw);
			return bw;
		}
		catch (Throwable ex) {
			throw new BeanCreationException(
					mbd.getResourceDescription(), beanName, "Instantiation of bean failed", ex);
		}
	}

從上面得知,不過是自動注入的,還是默認無參的構造函數都是調用實例化策略的instantiate()方法實例化bean的,那下面就去看看這個方法

instantiate()真正實現實例化

SimpleInstantiationStrategy.java

// 如果有需要覆蓋或動態替換的方法,則使用cglib進行動態代理(因爲可以在創建代理的同時將動態方法織入到類中)
		//但如果沒有需要動態改變的方法,爲了方便直接使用反射
		if (!bd.hasMethodOverrides()) {
			Constructor<?> constructorToUse;
			synchronized (bd.constructorArgumentLock) {
				constructorToUse = (Constructor<?>) bd.resolvedConstructorOrFactoryMethod;
				if (constructorToUse == null) {
					final Class<?> clazz = bd.getBeanClass();
					if (clazz.isInterface()) {
						throw new BeanInstantiationException(clazz, "Specified class is an interface");
					}
					try {
						if (System.getSecurityManager() != null) {
							constructorToUse = AccessController.doPrivileged(
									(PrivilegedExceptionAction<Constructor<?>>) clazz::getDeclaredConstructor);
						}
						else {
							constructorToUse =	clazz.getDeclaredConstructor();
						}
						bd.resolvedConstructorOrFactoryMethod = constructorToUse;
					}
					catch ...
				}
			}
			return BeanUtils.instantiateClass(constructorToUse);
		}
		else {
			// 使用了replace或者lookup的配置方法
			return instantiateWithMethodInjection(bd, beanName, owner);
		}
	}

通過SimpleInstantiationStrategy策略的instantiate()真正實現實例化了bean.

2.populateBean()填充屬性

protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
		if (bw == null) {
			if (mbd.hasPropertyValues()) {
				throw new BeanCreationException(
						mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
			}
			else {
				// Skip property population phase for null instance.
				return;
			}
		}

		// 給InstantiationAwareBeanPostProcessors最後一次機會在屬性注入前修改Bean的屬性值
		// 1.具體通過調用postProcessAfterInstantiation方法,如果調用返回false,表示不必繼續進行依賴注入,直接返回
		boolean continueWithPropertyPopulation = true;

		if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
			for (BeanPostProcessor bp : getBeanPostProcessors()) {
				if (bp instanceof InstantiationAwareBeanPostProcessor) {
					InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
					//判斷是否繼續填充 bean
					if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
						continueWithPropertyPopulation = false;
						break;
					}
				}
			}
		}

		//如果後處理器發出停止填充命令則終止後續的執行
		if (!continueWithPropertyPopulation) {
			return;
		}

		PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);

		// 根據Bean配置的依賴注入方式完成注入,默認是0,即不走以下邏輯,所有的依賴注入都需要在xml文件中有顯式的配置
		// 如果設置了相關的依賴裝配方式,會遍歷Bean中的屬性,根據類型或名稱來完成相應注入,無需額外配置
		if (mbd.getResolvedAutowireMode() == AUTOWIRE_BY_NAME || mbd.getResolvedAutowireMode() == AUTOWIRE_BY_TYPE) {
			// 深拷貝當前已有的配置
			MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
			// 根據名稱進行注入
			if (mbd.getResolvedAutowireMode() == AUTOWIRE_BY_NAME) {
				autowireByName(beanName, mbd, bw, newPvs);
			}
			// 根據類型進行注入
			if (mbd.getResolvedAutowireMode() == AUTOWIRE_BY_TYPE) {
				autowireByType(beanName, mbd, bw, newPvs);
			}
			// 結合注入後的配置,覆蓋當前配置
			pvs = newPvs;
		}

		//3.後處理器是否已經初始化
		boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
		//是否需要循環依賴檢查
		boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);

		if (hasInstAwareBpps || needsDepCheck) {
			if (pvs == null) {
				pvs = mbd.getPropertyValues();
			}
			// 過濾出所有需要進行依賴檢查的屬性編輯器
			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) {
				// 檢查是否滿足相關依賴關係,對應的depends-on屬性,需要確保所有依賴的Bean先完成初始化
				checkDependencies(beanName, mbd, filteredPds, pvs);
			}
		}

		if (pvs != null) {
			// 4.將pvs上所有的屬性填充到BeanWrapper對應的Bean實例中,注意到這一步,TestBean的student屬性還是RuntimeBeanReference,即還未解析實際的Student實例
			applyPropertyValues(beanName, mbd, bw, pvs);
		}
	}

此方法的代碼步驟:

  1. 執行InstantiationAwareBeanPostProcessors處理器的postProcessAfterInstantiation()方法,控制程序是否繼續進行屬性填充。
  2. 根據注入類型(byName\byType),提取依賴的bean,並統一存入PropertyValues中。
  3. 執行InstantiationAwareBeanPostProcessors處理器的postProcessPropertyValues()方法,在獲取屬性完成 填充屬性前 對屬性的再次處理。
  4. 將所有的PropertyValues中的屬性填充至BeanWrapper中。
    這裏有三個關鍵函數autowireByName、autowireByType、applyPropertyValues,下面就這個三個函數展開。
autowireByName()
protected void autowireByName(
			String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {

		// 根據bw的PropertyDescriptors,遍歷出所有可寫的(即set方法存在),存在於BeanDefinition裏的PropertyValues,且不是簡單屬性的屬性名
		// 簡單屬性的判定參照下面方法,主要涵蓋基本類型及其包裝類,Number,Date等
		String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);
		for (String propertyName : propertyNames) {
			if (containsBean(propertyName)) {
				// 遞歸初始化相關Bean
				Object bean = getBean(propertyName);
				// 根據名稱添加到pvs中
				pvs.add(propertyName, bean);
				// 註冊依賴關係
				registerDependentBean(propertyName, beanName);
				if (logger.isDebugEnabled()) {
					logger.debug("Added autowiring by name from bean name '" + beanName +
							"' via property '" + propertyName + "' to bean named '" + propertyName + "'");
				}
			}
			else {
				if (logger.isTraceEnabled()) {
					logger.trace("Not autowiring property '" + propertyName + "' of bean '" + beanName +
							"' by name: no matching bean found");
				}
			}
		}
	}
autowireByType()
protected void autowireByType(
			String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {
		// 獲取類型轉換器
		TypeConverter converter = getCustomTypeConverter();
		if (converter == null) {
			converter = bw;
		}

		Set<String> autowiredBeanNames = new LinkedHashSet<>(4);
		// 類似的,過濾出滿足裝配條件的Bean屬性
		String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);
		for (String propertyName : propertyNames) {
			try {
				PropertyDescriptor pd = bw.getPropertyDescriptor(propertyName);
				// 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()) {
					// 獲取相關的setter方法參數
					MethodParameter methodParam = BeanUtils.getWriteMethodParameter(pd);
					// // 定義是否允許懶加載。
					boolean eager = !PriorityOrdered.class.isInstance(bw.getWrappedInstance());
					DependencyDescriptor desc = new AutowireByTypeDependencyDescriptor(methodParam, eager);
					// 這裏會根據傳入desc裏的入參類型,作爲依賴裝配的類型
					// 再根據這個類型在BeanFacoty中查找所有類或其父類相同的BeanName
					// 最後根據BeanName獲取或初始化相應的類,然後將所有滿足條件的BeanName填充到autowiredBeanNames中。
					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.clear();
				}
			}
			catch (BeansException ex) {
				throw new UnsatisfiedDependencyException(mbd.getResourceDescription(), beanName, propertyName, ex);
			}
		}
	}
applyPropertyValues()
protected void applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs) {
		if (pvs.isEmpty()) {
			return;
		}

		if (System.getSecurityManager() != null && bw instanceof BeanWrapperImpl) {
			((BeanWrapperImpl) bw).setSecurityContext(getAccessControlContext());
		}

		MutablePropertyValues mpvs = null;
		List<PropertyValue> original;

		if (pvs instanceof MutablePropertyValues) {
			mpvs = (MutablePropertyValues) pvs;
			//如果mpvs中的值已經被轉換爲對應的類型那麼可以直接設置到beanwapper中
			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 {
			//如果pvs並不是使用MutablePropertyValues封裝的類型,那麼直接使用原始的屬性獲取方法
			original = Arrays.asList(pvs.getPropertyValues());
		}

		TypeConverter converter = getCustomTypeConverter();
		if (converter == null) {
			converter = bw;
		}
		//獲取對應的解析器
		BeanDefinitionValueResolver valueResolver = new BeanDefinitionValueResolver(this, beanName, mbd, converter);

		// Create a deep copy, resolving any references for values.
		List<PropertyValue> deepCopy = new ArrayList<>(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);
				}
				// 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);
		}
	}

3. bean的初始化

protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
		if (System.getSecurityManager() != null) {
			AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
				invokeAwareMethods(beanName, bean);
				return null;
			}, getAccessControlContext());
		}
		else {
			//對特殊的bean處理:Aware、BeanClassLoaderAware、BeanFactoryAware
			invokeAwareMethods(beanName, bean);
		}

		Object wrappedBean = bean;
		if (mbd == null || !mbd.isSynthetic()) {
			//應用後處理器
			wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
		}

		try {
			///激活用戶自定義的init方法
			invokeInitMethods(beanName, wrappedBean, mbd);
		}
		catch (Throwable ex) {
			throw new BeanCreationException(
					(mbd != null ? mbd.getResourceDescription() : null),
					beanName, "Invocation of init method failed", ex);
		}
		if (mbd == null || !mbd.isSynthetic()) {
			//應用後處理器
			wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
		}

		return wrappedBean;
	}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章