1. 程式人生 > >Spring原始碼學習(三)炒雞丁與populateBean沒區別

Spring原始碼學習(三)炒雞丁與populateBean沒區別

的postProcessAfterInstantiation

(在設定屬性前去修改Bean的狀態,也可以控制是否繼續填充Bean)

作為一個已婚男人炒菜之前,請示老婆,這很重要。

我:“我炒宮爆雞丁了,有特殊要求嗎?”

老婆大人:“沒有要求,炒吧”。

2.注入屬性到PropertyValues中(autowireByName/autowireByType)

初步準備食材

準備雞肉,郫縣豆瓣醬,花生米,黃瓜

3.執行InstantiationAwareBeanPostProcessor的postProcessPropertyValues,

對解析完但未設定的屬性再進行處理

切菜 雞肉切丁,黃瓜切小塊。 4.對dependency-check屬性的支援,預設是不校驗   5.將PropertyValues中的屬性值設定到BeanWrapper中 下鍋,炒熟出鍋

autowirebyType的大致邏輯

看了原始碼總結如下:

  1. 不處理簡單屬性,即不處理:Enum,CharSequence,Number,Date,URI,Locale等。(具體可以檢視org.springframework.beans.BeanUtils#isSimpleProperty這個方法。)
  2. 不對Object型別的屬性進行自動注入, 沒有意義,技術無法實現
  3. 解析依賴resolveDependency並設定到pvs中
  4. registerDependentBean 註冊當前依賴。

autowiredByType的原始碼註釋

/**
	 * Abstract method defining "autowire by type" (bean properties by type) behavior.
	 * 抽象方法 定義 按型別注入
	 * <p>This is like PicoContainer default, in which there must be exactly one bean
	 * of the property type in the bean factory. This makes bean factories simple to
	 * configure for small namespaces, but doesn't work as well as standard Spring
	 * behavior for bigger applications.
	 * 類似PicoContainer(非常輕量級的Ioc容器),beanFactory中一個屬性型別必須有一個確切對應的bean
	 * bean工廠很容易配置小的名稱空間.
	 * @param beanName the name of the bean to autowire by type  需要按型別注入的BeanName
	 * @param mbd the merged bean definition to update through autowiring   合併後的BeanDefinition
	 * @param bw the BeanWrapper from which we can obtain information about the bean  BeanWrapper物件
	 * @param pvs the PropertyValues to register wired objects with 註冊屬性的屬性值
	 */
	protected void autowireByType(
			String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {
		//獲取型別轉換器
		TypeConverter converter = getCustomTypeConverter();
		if (converter == null) {
			converter = bw;
		}
		//獲取需要 注入的 非簡單型別
		/**
		 * 簡單型別,詳見
		 * @see org.springframework.beans.BeanUtils#isSimpleProperty
		 */
		Set<String> autowiredBeanNames = new LinkedHashSet<>(4);
		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()) {
					//獲得屬性寫的方法
					MethodParameter methodParam = BeanUtils.getWriteMethodParameter(pd);
					// Do not allow eager init for type matching in case of a prioritized post-processor.
					// 假如實現了prioritized post-processor ,在進行型別匹配時,是不允許,eager初始化(熱載入)的
					boolean eager = !PriorityOrdered.class.isInstance(bw.getWrappedInstance());
					DependencyDescriptor desc = new AutowireByTypeDependencyDescriptor(methodParam, eager);
					//解析依賴
					Object autowiredArgument = resolveDependency(desc, beanName, autowiredBeanNames, converter);
					if (autowiredArgument != null) {
						pvs.add(propertyName, autowiredArgument);
					}
					for (String autowiredBeanName : autowiredBeanNames) {
						//註冊依賴
						registerDependentBean(autowiredBeanName, beanName);
						if (logger.isTraceEnabled()) {
							logger.trace("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);
			}
		}
	}


下回寫resolveDependency的邏輯。

一圖勝千言

原始碼註釋


	/**
	 * Populate the bean instance in the given BeanWrapper with the property values
	 * from the bean definition.
	 * 填充bean的屬性
	 * @param beanName the name of the bean   bean的名稱
	 * @param mbd the bean definition for the bean 合併後的Bean的定義
	 * @param bw the BeanWrapper with bean instance   beanWrapper的物件
	 */
	@SuppressWarnings("deprecation")  // for postProcessPropertyValues
	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.
				// 跳過沒有屬性,null例項
				return;
			}
		}

		// 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.
		//給任何InstantiationWareBeanPostProcessors在設定屬性之前修改bean的狀態的機會。
		// 例如,這可用於支援屬性注入
		boolean continueWithPropertyPopulation = true;
		//InstantiationWareBeanPostProcessors  可以控制是否繼續填充bean
		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;
		}

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

		if (mbd.getResolvedAutowireMode() == AUTOWIRE_BY_NAME || mbd.getResolvedAutowireMode() == AUTOWIRE_BY_TYPE) {
			MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
			// Add property values based on autowire by name if applicable.
			if (mbd.getResolvedAutowireMode() == AUTOWIRE_BY_NAME) {
				//根據名稱自動注入
				autowireByName(beanName, mbd, bw, newPvs);
			}
			// Add property values based on autowire by type if applicable.
			if (mbd.getResolvedAutowireMode() == AUTOWIRE_BY_TYPE) {
				//根據型別自動注入
				autowireByType(beanName, mbd, bw, newPvs);
			}
			pvs = newPvs;
		}

		boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
		boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);

		PropertyDescriptor[] filteredPds = null;
		if (hasInstAwareBpps) {
			//有InstantiationAwareBeanPostProcessors 物件
			if (pvs == null) {
				pvs = mbd.getPropertyValues();
			}
			for (BeanPostProcessor bp : getBeanPostProcessors()) {
				if (bp instanceof InstantiationAwareBeanPostProcessor) {
					InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
					PropertyValues pvsToUse = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
					if (pvsToUse == null) {
						if (filteredPds == null) {
							filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
						}
						pvsToUse = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
						if (pvsToUse == null) {
							return;
						}
					}
					pvs = pvsToUse;
				}
			}
		}
		if (needsDepCheck) {
			if (filteredPds == null) {
				filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
			}
			//檢查依賴Dependency-check
			checkDependencies(beanName, mbd, filteredPds, pvs);
		}

		if (pvs != null) {
			//將屬性值設定到Bean中
			applyPropertyValues(beanName, mbd, bw, pvs);
		}
	}


下一篇resolveDependenc