zoukankan      html  css  js  c++  java
  • XML配置下Spring Bean的注入

    主题

    之前学习了@Autowired下SpringBean是怎么注入到属性中的.

    https://www.cnblogs.com/abcwt112/p/12541783.html

    现在学习下远古时代的XML是怎么注入的.

    Ac初始化

    入口是XML的AC.

    new的时候回做refresh方法

    refresh之前的文章分享过大致做了什么

    https://www.cnblogs.com/abcwt112/p/12388982.html

     其中这一步会去掉BeanFactory的getBean方法去初始化配置的bean.

    属性注入

    BF的getBean里面有无数逻辑.其中注入属性的是这一段

    org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#populateBean

     1 /**
     2      * Populate the bean instance in the given BeanWrapper with the property values
     3      * from the bean definition.
     4      * @param beanName the name of the bean
     5      * @param mbd the bean definition for the bean
     6      * @param bw the BeanWrapper with bean instance
     7      */
     8     @SuppressWarnings("deprecation")  // for postProcessPropertyValues
     9     protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
    10         if (bw == null) {
    11             if (mbd.hasPropertyValues()) {
    12                 throw new BeanCreationException(
    13                         mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
    14             }
    15             else {
    16                 // Skip property population phase for null instance.
    17                 return;
    18             }
    19         }
    20 
    21         // Give any InstantiationAwareBeanPostProcessors the opportunity to modify the
    22         // state of the bean before properties are set. This can be used, for example,
    23         // to support styles of field injection.
    24         boolean continueWithPropertyPopulation = true;
    25 
    26         if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
    27             for (BeanPostProcessor bp : getBeanPostProcessors()) {
    28                 if (bp instanceof InstantiationAwareBeanPostProcessor) {
    29                     InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
    30                     if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
    31                         continueWithPropertyPopulation = false;
    32                         break;
    33                     }
    34                 }
    35             }
    36         }
    37 
    38         if (!continueWithPropertyPopulation) {
    39             return;
    40         }
    41 
    42         PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);
    43 
    44         int resolvedAutowireMode = mbd.getResolvedAutowireMode();
    45         if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
    46             MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
    47             // Add property values based on autowire by name if applicable.
    48             if (resolvedAutowireMode == AUTOWIRE_BY_NAME) {
    49                 autowireByName(beanName, mbd, bw, newPvs);
    50             }
    51             // Add property values based on autowire by type if applicable.
    52             if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
    53                 autowireByType(beanName, mbd, bw, newPvs);
    54             }
    55             pvs = newPvs;
    56         }
    57 
    58         boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
    59         boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);
    60 
    61         PropertyDescriptor[] filteredPds = null;
    62         if (hasInstAwareBpps) {
    63             if (pvs == null) {
    64                 pvs = mbd.getPropertyValues();
    65             }
    66             for (BeanPostProcessor bp : getBeanPostProcessors()) {
    67                 if (bp instanceof InstantiationAwareBeanPostProcessor) {
    68                     InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
    69                     PropertyValues pvsToUse = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
    70                     if (pvsToUse == null) {
    71                         if (filteredPds == null) {
    72                             filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
    73                         }
    74                         pvsToUse = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
    75                         if (pvsToUse == null) {
    76                             return;
    77                         }
    78                     }
    79                     pvs = pvsToUse;
    80                 }
    81             }
    82         }
    83         if (needsDepCheck) {
    84             if (filteredPds == null) {
    85                 filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
    86             }
    87             checkDependencies(beanName, mbd, filteredPds, pvs);
    88         }
    89 
    90         if (pvs != null) {
    91             applyPropertyValues(beanName, mbd, bw, pvs);
    92         }
    93     }

    如果XML里bean是这样配置的:

     其中最后91行的 applyPropertyValues(beanName, mbd, bw, pvs);

    就是把对象中的属性(pvs)转化成对象,设置到bw(BeanWrapper.封装了原始对象)中去.

    比如beanName是a.     pvs是a对象里的属性集,其中包含b

    具体逻辑是调用Object resolvedValue = valueResolver.resolveValueIfNecessary(pv, originalValue); 来获取要注入的属性对应的bean.

     最终也是通过BF.getBean去取Bean.再set到beanwrapper上去.

    XML配置中还有一种情况是使用默认的自动配置

    这个时候bean的属性是不需要配置的.spring会自动根据类型(byType)或者名称(byName)去匹配.

    原理是在org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#populateBean中

     1         int resolvedAutowireMode = mbd.getResolvedAutowireMode();
     2         if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
     3             MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
     4             // Add property values based on autowire by name if applicable.
     5             if (resolvedAutowireMode == AUTOWIRE_BY_NAME) {
     6                 autowireByName(beanName, mbd, bw, newPvs);
     7             }
     8             // Add property values based on autowire by type if applicable.
     9             if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
    10                 autowireByType(beanName, mbd, bw, newPvs);
    11             }
    12             pvs = newPvs;
    13         }

    resolvedAutowireMode默认情况下是0.是不会自动装配的.如果配置了就会进对应的autowiredByXXX方法.会找出missing property values然后设置到MutablePropertyValues中.所以最后掉applyPropertyValues方法的时候还是会填充这些属性.

  • 相关阅读:
    用Twebbrowser做可控编辑器与MSHTML(调用js)
    用Twebbrowser做可控编辑器与MSHTML(插入表格)
    用Twebbrowser做可控编辑器与MSHTML
    如何用firefox57看中国大学mooc视频
    学习EXTJS6(8)基本功能-表单的基础表字段Ext.form.field.Basic
    学习EXTJS6(7)基本功能-最常用的表单
    学习EXTJS6(6)基本功能-工具栏和菜单
    学习EXTJS6(5)基本功能-进度条组件
    学习EXTJS6(4)基本功能-信息提示框组件
    学习EXTJS6(3)基本概念
  • 原文地址:https://www.cnblogs.com/abcwt112/p/12557232.html
Copyright © 2011-2022 走看看