­

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

  • 2019 年 10 月 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);  		}  	}