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的大致逻辑
看了源码总结如下:
- 不处理简单属性,即不处理:Enum,CharSequence,Number,Date,URI,Locale等。(具体可以查看org.springframework.beans.BeanUtils#isSimpleProperty这个方法。)
- 不对Object类型的属性进行自动注入, 没有意义,技术无法实现
- 解析依赖resolveDependency并设置到pvs中
- 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); } }