Spring源码学习(三)炒鸡丁与populateBean没区别

860 阅读4分钟

逻辑说明

populateBean的流程 炒鸡丁的流程
1.执行InstantiationAwareBeanPostProcessor的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);
		}
	}


下一篇resolveDependency 预计10月7号前