• spring源码学习之bean的加载(二)


      这是接着上篇继续写bean的加载过程,好像是有点太多了,因为bean的加载过程是很复杂的,要处理的情况有很多,继续。。。

    7、创建bean

    常规的bean的创建时通过doCreateBean方法来实现的
    这个方法在org.springframework.beans.factory.support包下AbstractAutowireCapableBeanFactory类下

      1 /**
      2  * Actually create the specified bean. Pre-creation processing has already happened
      3  * at this point, e.g. checking {@code postProcessBeforeInstantiation} callbacks.
      4  * <p>Differentiates between default bean instantiation, use of a
      5  * factory method, and autowiring a constructor.
      6  * @param beanName the name of the bean
      7  * @param mbd the merged bean definition for the bean
      8  * @param args explicit arguments to use for constructor or factory method invocation
      9  * @return a new instance of the bean
     10  * @throws BeanCreationException if the bean could not be created
     11  * @see #instantiateBean
     12  * @see #instantiateUsingFactoryMethod
     13  * @see #autowireConstructor
     14  */
     15 protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
     16         throws BeanCreationException {
     17 
     18     // Instantiate the bean.
     19     BeanWrapper instanceWrapper = null;
     20     if (mbd.isSingleton()) {
     21         instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
     22     }
     23     // 根据指定bean使用对应的策略创建新的实例,如:工厂方法、构造函数自动注入、简单初始化
     24     if (instanceWrapper == null) {
     25         instanceWrapper = createBeanInstance(beanName, mbd, args);
     26     }
     27     final Object bean = instanceWrapper.getWrappedInstance();
     28     Class<?> beanType = instanceWrapper.getWrappedClass();
     29     if (beanType != NullBean.class) {
     30         mbd.resolvedTargetType = beanType;
     31     }
     32 
     33     // Allow post-processors to modify the merged bean definition.
     34     synchronized (mbd.postProcessingLock) {
     35         if (!mbd.postProcessed) {
     36             try {
     37                 // 应用MergedBeanDefinitionPostProcessors
     38                 applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
     39             }
     40             catch (Throwable ex) {
     41                 throw new BeanCreationException(mbd.getResourceDescription(), beanName,
     42                         "Post-processing of merged bean definition failed", ex);
     43             }
     44             mbd.postProcessed = true;
     45         }
     46     }
     47 
     48     // Eagerly cache singletons to be able to resolve circular references
     49     // even when triggered by lifecycle interfaces like BeanFactoryAware.
     50     // 是否需要提早曝光:单例&允许循环依赖&当前bean正在创建中,检测循环依赖
     51     boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
     52             isSingletonCurrentlyInCreation(beanName));
     53     if (earlySingletonExposure) {
     54         if (logger.isDebugEnabled()) {
     55             logger.debug("Eagerly caching bean '" + beanName +
     56                     "' to allow for resolving potential circular references");
     57         }
     58         //为避免后期循环依赖,可以在bean初始化完成前将创建实例的ObjectFactory加入工厂
     59         addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
     60     }
     61 
     62     // Initialize the bean instance.
     63     Object exposedObject = bean;
     64     try {
     65         // 对bean进行填充,将各个属性值注入,其中,可能存在依赖于其他bean的属性,则会递归初始依赖bean
     66         populateBean(beanName, mbd, instanceWrapper);
     67         // 初始化bean
     68         exposedObject = initializeBean(beanName, exposedObject, mbd);
     69     }
     70     catch (Throwable ex) {
     71         if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
     72             throw (BeanCreationException) ex;
     73         }
     74         else {
     75             throw new BeanCreationException(
     76                     mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
     77         }
     78     }
     79 
     80     if (earlySingletonExposure) {
     81         Object earlySingletonReference = getSingleton(beanName, false);
     82         // earlySingletonReference只有在检测到有循环依赖的情况下才会不为空
     83         if (earlySingletonReference != null) {
     84             // 如果exposedObject没有在初始化方法中被改变,也就是没有被增强
     85             if (exposedObject == bean) {
     86                 exposedObject = earlySingletonReference;
     87             }
     88             else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
     89                 String[] dependentBeans = getDependentBeans(beanName);
     90                 Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
     91                 for (String dependentBean : dependentBeans) {
     92                     // 检测依赖
     93                     if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
     94                         actualDependentBeans.add(dependentBean);
     95                     }
     96                 }
     97                 // 因为bean创建后其所依赖的bean一定已经创建的
     98                 // actualDependentBeans不为空则表示当前bean创建后其依赖的bean却没有被全部创建完,存在循环依赖
     99                 if (!actualDependentBeans.isEmpty()) {
    100                     throw new BeanCurrentlyInCreationException(beanName,
    101                             "Bean with name '" + beanName + "' has been injected into other beans [" +
    102                             StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +
    103                             "] in its raw version as part of a circular reference, but has eventually been " +
    104                             "wrapped. This means that said other beans do not use the final version of the " +
    105                             "bean. This is often the result of over-eager type matching - consider using " +
    106                             "'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example.");
    107                 }
    108             }
    109         }
    110     }
    111 
    112     // Register bean as disposable.
    113     try {
    114         // 根据scope注册bean
    115         registerDisposableBeanIfNecessary(beanName, bean, mbd);
    116     }
    117     catch (BeanDefinitionValidationException ex) {
    118         throw new BeanCreationException(
    119                 mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
    120     }
    121 
    122     return exposedObject;
    123 }

    (1)如果是单例,则需要首先清除缓存
    (2)实例化bean,将BeanDefinition转换成BeanWrapper,转化是一个复杂过程,大致思路如下
    如果存在工厂方法则使用工厂方法进行初始化
    一个类有多个构造函数,每个构造函数都有不同的参数,所以需要根据参数锁定构造函数并进行初始化
    如果即不存在工厂方法,也没有指定构造方法,则使用指定的构造方法初始化bean
    (3)MergedBeanDefinitionPostProcessors的应用
    bean合并后处理,autowire注解正是通过此方法实现注入类型的预解析
    (4)依赖处理
    (5)属性填充。将所有属性填充到bean的实例中
    (6)循环依赖检查
    之前提到过,在spring中解决循环依赖只对单例有效,而对于prototype的bean,spring没有更好的解决办法,唯一要做的是抛出异常。
    (7)注册DisposableBean
    如果配置了destroy-method,这里需要注册以便于在销毁时候调用
    (8)完成创建并返回

    来吧,中间还有大量的源码来实现每一部分的功能,这个是挺复杂的,开始吧,一个一个的来探索
    7.1 创建bean实例

    首先从createBeanInstance()方法开始,这个方法在org.springframework.beans.factory.support包下AbstractAutowireCapableBeanFactory类下

     1 /**
     2  * Create a new instance for the specified bean, using an appropriate instantiation strategy:
     3  * factory method, constructor autowiring, or simple instantiation.
     4  * @param beanName the name of the bean
     5  * @param mbd the bean definition for the bean
     6  * @param args explicit arguments to use for constructor or factory method invocation
     7  * @return a BeanWrapper for the new instance
     8  * @see #obtainFromSupplier
     9  * @see #instantiateUsingFactoryMethod
    10  * @see #autowireConstructor
    11  * @see #instantiateBean
    12  */
    13 protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
    14     // Make sure bean class is actually resolved at this point.
    15     // 解析Class
    16     Class<?> beanClass = resolveBeanClass(mbd, beanName);
    17 
    18     if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) {
    19         throw new BeanCreationException(mbd.getResourceDescription(), beanName,
    20                 "Bean class isn't public, and non-public access not allowed: " + beanClass.getName());
    21     }
    22 
    23     Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
    24     if (instanceSupplier != null) {
    25         return obtainFromSupplier(instanceSupplier, beanName);
    26     }
    27 
    28     // 如果工厂方法不为空则使用工厂方法初始化策略
    29     if (mbd.getFactoryMethodName() != null) {
    30         return instantiateUsingFactoryMethod(beanName, mbd, args);
    31     }
    32 
    33     // Shortcut when re-creating the same bean...
    34     boolean resolved = false;
    35     boolean autowireNecessary = false;
    36     if (args == null) {
    37         synchronized (mbd.constructorArgumentLock) {
    38             // 一个类有多个构造函数,每个构造函数都有不同的参数,所以调用钱需要先根据参数锁定构造函数或者是工厂方法
    39             if (mbd.resolvedConstructorOrFactoryMethod != null) {
    40                 resolved = true;
    41                 autowireNecessary = mbd.constructorArgumentsResolved;
    42             }
    43         }
    44     }
    45     // 如果已经解析过则使用解析好的构造函数不需要再次锁定
    46     if (resolved) {
    47         if (autowireNecessary) {
    48             // 构造函数自动注入
    49             return autowireConstructor(beanName, mbd, null, null);
    50         }
    51         else {
    52             // 使用默认的构造函数
    53             return instantiateBean(beanName, mbd);
    54         }
    55     }
    56 
    57     // Candidate constructors for autowiring?
    58     // 需要根据参数解析构造函数
    59     Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
    60     if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
    61             mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
    62         // 构造函数自动注入
    63         return autowireConstructor(beanName, mbd, ctors, args);
    64     }
    65 
    66     // No special handling: simply use no-arg constructor.
    67     // 使用默认构造函数构造
    68     return instantiateBean(beanName, mbd);
    69 }

    大致梳理一下这个createBeanInstance()方法中的思路:
    (1)如果在RootBeanDefinition中存在factoryMethodName属性,或者说是在配置文件中配置了factory-method,那么spring会尝试使用
    instantiateUsingFactoryMethod(beanName, mbd, args)方法根据RootBeanDefiniton中配置生成bean的实例
    (2)解析构造函数并进行构造函数的实例化,因为一个bean对应的类中可能会有多个构造函数,而每个构造函数的参数不同,spring会根据参数以及类型
    去判断最终会使用哪个构造函数进行实例化。但是,判断过程是比较消耗性能的,所以采用缓存机制,如果已经解析过了,则不需要重复解析,而是直接从
    RootBeanDefinition中的属性resolvedConstructorOrFactoryMethod缓存的值去取,否则需要再次解析,并将结果添加至RootBeanDefinition中的属性
    resolvedConstructorOrFactoryMethod中

    1、autowireConstructor

    对于实例的创建spring中分成了两种情况,一种是通用的实例化,另一种是带有参数的实例化,带有参数的实例化相当复杂,因为存在着不确定性,所以在判断
    对应参数上做了大量工作

    org.springframework.beans.factory.support包下AbstractAutowireCapableBeanFactory类下createBeanInstance()方法
    从这段代码继续向下寻找,找到真正的逻辑代码

    // 构造函数自动注入
    return autowireConstructor(beanName, mbd, ctors, args);

    org.springframework.beans.factory.support包下AbstractAutowireCapableBeanFactory类

    1 protected BeanWrapper autowireConstructor(
    2         String beanName, RootBeanDefinition mbd, @Nullable Constructor<?>[] ctors, @Nullable Object[] explicitArgs) {
    3 
    4     return new ConstructorResolver(this).autowireConstructor(beanName, mbd, ctors, explicitArgs);
    5 }

    真正的代码其实在这个方法中
    org.springframework.beans.factory.support包下ConstructorResolver类下的autowireConstructor方法

      1 public BeanWrapper autowireConstructor(String beanName, RootBeanDefinition mbd,
      2         @Nullable Constructor<?>[] chosenCtors, @Nullable Object[] explicitArgs) {
      3 
      4     BeanWrapperImpl bw = new BeanWrapperImpl();
      5     this.beanFactory.initBeanWrapper(bw);
      6 
      7     Constructor<?> constructorToUse = null;
      8     ArgumentsHolder argsHolderToUse = null;
      9     Object[] argsToUse = null;
     10 
     11     // explicitArgs通过getBean方法传入,如果getBean方法调用的时候指定方法参数那么直接使用
     12     if (explicitArgs != null) {
     13         argsToUse = explicitArgs;
     14     }
     15     else {
     16         // 如果在getBean方法时候没有指定则尝试从配置文件中解析
     17         Object[] argsToResolve = null;
     18         synchronized (mbd.constructorArgumentLock) {
     19             constructorToUse = (Constructor<?>) mbd.resolvedConstructorOrFactoryMethod;
     20             if (constructorToUse != null && mbd.constructorArgumentsResolved) {
     21                 // Found a cached constructor...
     22                 // 尝试从缓存中获取
     23                 argsToUse = mbd.resolvedConstructorArguments;
     24                 if (argsToUse == null) {
     25                     // 配置的构造函数参数
     26                     argsToResolve = mbd.preparedConstructorArguments;
     27                 }
     28             }
     29         }
     30         
     31         // 如果缓存中存在
     32         if (argsToResolve != null) {
     33             // 解析参数类型,如给定方法的构造参数A(int,int),经过此方法后就会将配置中的("1","1")转换为(1,1)
     34             // 缓存中的值可能是原始值 也可能是最终值
     35             argsToUse = resolvePreparedArguments(beanName, mbd, bw, constructorToUse, argsToResolve);
     36         }
     37     }
     38 
     39     // 没有被缓存
     40     if (constructorToUse == null) {
     41         // Need to resolve the constructor.
     42         // 需要解析构造函数
     43         boolean autowiring = (chosenCtors != null ||
     44                 mbd.getResolvedAutowireMode() == AutowireCapableBeanFactory.AUTOWIRE_CONSTRUCTOR);
     45         ConstructorArgumentValues resolvedValues = null;
     46 
     47         int minNrOfArgs;
     48         if (explicitArgs != null) {
     49             minNrOfArgs = explicitArgs.length;
     50         }
     51         else {
     52             // 提取配置文件中配置的构造函数参数
     53             ConstructorArgumentValues cargs = mbd.getConstructorArgumentValues();
     54             // 用于承载解析后的构造参数值
     55             resolvedValues = new ConstructorArgumentValues();
     56             // 能解析到的参数的个数
     57             minNrOfArgs = resolveConstructorArguments(beanName, mbd, bw, cargs, resolvedValues);
     58         }
     59 
     60         // Take specified constructors, if any.
     61         Constructor<?>[] candidates = chosenCtors;
     62         if (candidates == null) {
     63             Class<?> beanClass = mbd.getBeanClass();
     64             try {
     65                 candidates = (mbd.isNonPublicAccessAllowed() ?
     66                         beanClass.getDeclaredConstructors() : beanClass.getConstructors());
     67             }
     68             catch (Throwable ex) {
     69                 throw new BeanCreationException(mbd.getResourceDescription(), beanName,
     70                         "Resolution of declared constructors on bean Class [" + beanClass.getName() +
     71                         "] from ClassLoader [" + beanClass.getClassLoader() + "] failed", ex);
     72             }
     73         }
     74         // 排序给定的构造函数 public构造函数优先参数数量降序、非public构造函数参数数量降序
     75         AutowireUtils.sortConstructors(candidates);
     76         int minTypeDiffWeight = Integer.MAX_VALUE;
     77         Set<Constructor<?>> ambiguousConstructors = null;
     78         LinkedList<UnsatisfiedDependencyException> causes = null;
     79 
     80         for (Constructor<?> candidate : candidates) {
     81             Class<?>[] paramTypes = candidate.getParameterTypes();
     82 
     83             if (constructorToUse != null && argsToUse.length > paramTypes.length) {
     84                 // Already found greedy constructor that can be satisfied ->
     85                 // do not look any further, there are only less greedy constructors left.
     86                 // 如果已经找到选用的构造参数或者需要的参数个数小于当前构造参数个数则终止
     87                 // 因为已经按照参数个数降序排列
     88                 break;
     89             }
     90             if (paramTypes.length < minNrOfArgs) {
     91                 // 参数个数不相等
     92                 continue;
     93             }
     94 
     95             ArgumentsHolder argsHolder;
     96             if (resolvedValues != null) {
     97                 // 有参数则根据值构造对应参数类型的参数
     98                 try {
     99                     String[] paramNames = ConstructorPropertiesChecker.evaluate(candidate, paramTypes.length);
    100                     if (paramNames == null) {
    101                         // 注释上获取参数名称
    102                         ParameterNameDiscoverer pnd = this.beanFactory.getParameterNameDiscoverer();
    103                         if (pnd != null) {
    104                             // 获取指定构造函数的参数名称
    105                             paramNames = pnd.getParameterNames(candidate);
    106                         }
    107                     }
    108                     // 根据名称和类型创造参数持有者
    109                     argsHolder = createArgumentArray(beanName, mbd, resolvedValues, bw, paramTypes, paramNames,
    110                             getUserDeclaredConstructor(candidate), autowiring);
    111                 }
    112                 catch (UnsatisfiedDependencyException ex) {
    113                     if (logger.isTraceEnabled()) {
    114                         logger.trace("Ignoring constructor [" + candidate + "] of bean '" + beanName + "': " + ex);
    115                     }
    116                     // Swallow and try next constructor.
    117                     if (causes == null) {
    118                         causes = new LinkedList<>();
    119                     }
    120                     causes.add(ex);
    121                     continue;
    122                 }
    123             }
    124             else {
    125                 // Explicit arguments given -> arguments length must match exactly.
    126                 if (paramTypes.length != explicitArgs.length) {
    127                     continue;
    128                 }
    129                 // 构造函数没有参数的情况
    130                 argsHolder = new ArgumentsHolder(explicitArgs);
    131             }
    132 
    133             // 探测是否有不确定性的构造参数存在,例如不同构造函数的参数为父子关系
    134             int typeDiffWeight = (mbd.isLenientConstructorResolution() ?
    135                     argsHolder.getTypeDifferenceWeight(paramTypes) : argsHolder.getAssignabilityWeight(paramTypes));
    136             // Choose this constructor if it represents the closest match.
    137             // 如果它代表着当前最接近的匹配则选择作为构造函数
    138             if (typeDiffWeight < minTypeDiffWeight) {
    139                 constructorToUse = candidate;
    140                 argsHolderToUse = argsHolder;
    141                 argsToUse = argsHolder.arguments;
    142                 minTypeDiffWeight = typeDiffWeight;
    143                 ambiguousConstructors = null;
    144             }
    145             else if (constructorToUse != null && typeDiffWeight == minTypeDiffWeight) {
    146                 if (ambiguousConstructors == null) {
    147                     ambiguousConstructors = new LinkedHashSet<>();
    148                     ambiguousConstructors.add(constructorToUse);
    149                 }
    150                 ambiguousConstructors.add(candidate);
    151             }
    152         }
    153 
    154         if (constructorToUse == null) {
    155             if (causes != null) {
    156                 UnsatisfiedDependencyException ex = causes.removeLast();
    157                 for (Exception cause : causes) {
    158                     this.beanFactory.onSuppressedException(cause);
    159                 }
    160                 throw ex;
    161             }
    162             throw new BeanCreationException(mbd.getResourceDescription(), beanName,
    163                     "Could not resolve matching constructor " +
    164                     "(hint: specify index/type/name arguments for simple parameters to avoid type ambiguities)");
    165         }
    166         else if (ambiguousConstructors != null && !mbd.isLenientConstructorResolution()) {
    167             throw new BeanCreationException(mbd.getResourceDescription(), beanName,
    168                     "Ambiguous constructor matches found in bean '" + beanName + "' " +
    169                     "(hint: specify index/type/name arguments for simple parameters to avoid type ambiguities): " +
    170                     ambiguousConstructors);
    171         }
    172 
    173         if (explicitArgs == null) {
    174             // 将解析的构造函数加入缓存
    175             argsHolderToUse.storeCache(mbd, constructorToUse);
    176         }
    177     }
    178 
    179     try {
    180         final InstantiationStrategy strategy = beanFactory.getInstantiationStrategy();
    181         Object beanInstance;
    182 
    183         if (System.getSecurityManager() != null) {
    184             final Constructor<?> ctorToUse = constructorToUse;
    185             final Object[] argumentsToUse = argsToUse;
    186             beanInstance = AccessController.doPrivileged((PrivilegedAction<Object>) () ->
    187                     strategy.instantiate(mbd, beanName, beanFactory, ctorToUse, argumentsToUse),
    188                     beanFactory.getAccessControlContext());
    189         }
    190         else {
    191             beanInstance = strategy.instantiate(mbd, beanName, this.beanFactory, constructorToUse, argsToUse);
    192         }
    193 
    194         // 将构造函数的实例加入BeanInstance中
    195         bw.setBeanInstance(beanInstance);
    196         return bw;
    197     }
    198     catch (Throwable ex) {
    199         throw new BeanCreationException(mbd.getResourceDescription(), beanName,
    200                 "Bean instantiation via constructor failed", ex);
    201     }
    202 }

    这个方法代码量很大,感觉很乱,自己读这个源码肯定要掉的坑里了,看看作者是如何解析的:
    (1)构造函数参数的确定

    根据explicitArgs参数确定
    如果传入的参数explicitArgs不为空,那边可以直接确定参数,因为explicitArgs参数是在调用bean的时候用户指定的,在BeanFactory中存在这个代码:
    <T> T getBean(Class<T> requiredType, Object... args) throws BeansException;
    在获取bean的时候,用户不但可以指定bean名称还可以指定bean所对应的类的构造函数或者工厂方法的方法参数,主要用于静态工厂方法的调用,而这里
    是需要给定完全匹配的参数,所以,便可判断,如果传入参数explicitArgs不为空,则可以确定构造参数就是它。

    缓存中获取
    除此之外,确定参数的办法如果之前已经分析过了,也就是说构造函数参数已经记录在缓存中,那么便可以直接拿来使用,而且,在缓存中缓存的可能是参数
    的最终类型也可能是参数的初始类型,所以,即使在缓存中得到了参数,也需要经过类型转换器的过滤以确保参数类型与对应的构造函数参数类型完全对应

    配置文件中获取
    如果不能根据传入的参数explicitArgs确定构造函数的参数,也无法在缓存中获取相关信息,只能另辟蹊径
    分析从获取配置文件中配置的构造函数信息开始,spring中配置文件中的信息经过转换会通过BeanDefinition实例承载,也就是参数mbd中包含,那么可以通过
    mbd.getConstructorArgumentValues()来获取构造函数的信息,有了配置的信息便可以获取对应的参数值信息了,获取参数值的信息包括直接指定值,如:直接
    指定构造函数中某个值为原始类型String类型,或者是一个对其他bean的引用,而这一处理委托给resolveConstructorArguments方法,并返回解析到参数个数

    (2)构造函数的确定
    已经确定构造函数的参数,接下来就是根据构造函数参数在所有的构造函数中锁定构造函数,而匹配的方法就是根据参数的个数,所以匹配之前需要先将构造函数
    按照public构造函数优先参数数量降序,非public构造函数参数数量降序,这样可以在遍历的情况下迅速判断排在后面的构造函数参数个数是够符合条件
    由于在配置文件中并不是唯一限制使用参数位置索引的方式去创建,同样还支持指定参数名称进行设定参数值的情况,那么就需要确定构造函数中参数名称
    获取参数名称可以有两种方式:一种是通过注解的方式直接获取,另一种是使用spring中提供的工具类ParameterNameDiscoverer来获取,构造函数,参数名称
    参数类型、参数值都确定后就可以锁定构造函数以及转换对应的参数类型了

    (3)根据确定的构造函数转换对应的参数类型
    主要是使用spring中提供的类型转换器或者用户提供的自定义的类型转换器

    (4)构造函数不确定性的验证
    spring在这里又做了一次验证

    (5)根据实例化策略以及得到的构造函数以及构造函数参数实例化bean

    2、instantiateBean
    这个就是默认的无参数的构造方法,并没有什么处理逻辑,直接调用实例化策略进行实例化就可以了
    此方法在org.springframework.beans.factory.support包下AbstractAutowireCapableBeanFactory类下

     1 /**
     2  * Instantiate the given bean using its default constructor.
     3  * @param beanName the name of the bean
     4  * @param mbd the bean definition for the bean
     5  * @return a BeanWrapper for the new instance
     6  */
     7 protected BeanWrapper instantiateBean(final String beanName, final RootBeanDefinition mbd) {
     8     try {
     9         Object beanInstance;
    10         final BeanFactory parent = this;
    11         if (System.getSecurityManager() != null) {
    12             beanInstance = AccessController.doPrivileged((PrivilegedAction<Object>) () ->
    13                     getInstantiationStrategy().instantiate(mbd, beanName, parent),
    14                     getAccessControlContext());
    15         }
    16         else {
    17             beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, parent);
    18         }
    19         BeanWrapper bw = new BeanWrapperImpl(beanInstance);
    20         initBeanWrapper(bw);
    21         return bw;
    22     }
    23     catch (Throwable ex) {
    24         throw new BeanCreationException(
    25                 mbd.getResourceDescription(), beanName, "Instantiation of bean failed", ex);
    26     }
    27 }

    3、实例化策略
    其实,经过前面的分析,我们已经得到了实例化所需的相关信息,完全可以使用最简单的反射方法直接反射来构造实例对象,spring没有这么做,找到实例化方法
    instantiateBean()方法中的这行代码:
    beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, parent);
    中instantiate方法,然后找到此方法的实现类SimpleInstantiationStrategy中的方法的重写,这里有代码实现

     1 @Override
     2 public Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner) {
     3     // Don't override the class with CGLIB if no overrides.
     4     // 如果有需要覆盖或者动态替换的方法则当然需要使用CGLIB进行动态代理,因为可以在创建动态代理的同时将动态方法织入类中
     5     // 但是如果没有需要动态改变的方法为了方便直接反射就行
     6     if (!bd.hasMethodOverrides()) {
     7         Constructor<?> constructorToUse;
     8         synchronized (bd.constructorArgumentLock) {
     9             constructorToUse = (Constructor<?>) bd.resolvedConstructorOrFactoryMethod;
    10             if (constructorToUse == null) {
    11                 final Class<?> clazz = bd.getBeanClass();
    12                 if (clazz.isInterface()) {
    13                     throw new BeanInstantiationException(clazz, "Specified class is an interface");
    14                 }
    15                 try {
    16                     if (System.getSecurityManager() != null) {
    17                         constructorToUse = AccessController.doPrivileged(
    18                                 (PrivilegedExceptionAction<Constructor<?>>) clazz::getDeclaredConstructor);
    19                     }
    20                     else {
    21                         constructorToUse = clazz.getDeclaredConstructor();
    22                     }
    23                     bd.resolvedConstructorOrFactoryMethod = constructorToUse;
    24                 }
    25                 catch (Throwable ex) {
    26                     throw new BeanInstantiationException(clazz, "No default constructor found", ex);
    27                 }
    28             }
    29         }
    30         return BeanUtils.instantiateClass(constructorToUse);
    31     }
    32     else {
    33         // Must generate CGLIB subclass.
    34         return instantiateWithMethodInjection(bd, beanName, owner);
    35     }
    36 }

    instantiateWithMethodInjection()方法最终调用的是下面这个方法
    这个方法是在org.springframework.beans.factory.support包下CglibSubclassingInstantiationStrategy类中

     1 /**
     2  * Create a new instance of a dynamically generated subclass implementing the
     3  * required lookups.
     4  * @param ctor constructor to use. If this is {@code null}, use the
     5  * no-arg constructor (no parameterization, or Setter Injection)
     6  * @param args arguments to use for the constructor.
     7  * Ignored if the {@code ctor} parameter is {@code null}.
     8  * @return new instance of the dynamically generated subclass
     9  */
    10 public Object instantiate(@Nullable Constructor<?> ctor, @Nullable Object... args) {
    11     Class<?> subclass = createEnhancedSubclass(this.beanDefinition);
    12     Object instance;
    13     if (ctor == null) {
    14         instance = BeanUtils.instantiateClass(subclass);
    15     }
    16     else {
    17         try {
    18             Constructor<?> enhancedSubclassConstructor = subclass.getConstructor(ctor.getParameterTypes());
    19             // 这里用到了反射
    20             instance = enhancedSubclassConstructor.newInstance(args);
    21         }
    22         catch (Exception ex) {
    23             throw new BeanInstantiationException(this.beanDefinition.getBeanClass(),
    24                     "Failed to invoke constructor for CGLIB enhanced subclass [" + subclass.getName() + "]", ex);
    25         }
    26     }
    27     // SPR-10785: set callbacks directly on the instance instead of in the
    28     // enhanced class (via the Enhancer) in order to avoid memory leaks.
    29     Factory factory = (Factory) instance;
    30     factory.setCallbacks(new Callback[] {NoOp.INSTANCE,
    31             new LookupOverrideMethodInterceptor(this.beanDefinition, this.owner),
    32             new ReplaceOverrideMethodInterceptor(this.beanDefinition, this.owner)});
    33     return instance;
    34 }

    程序中,首先判断如果!bd.hasMethodOverrides()为空,也就是用户没有使用replace或者lookup的配置方法,那么直接使用反射的方式,但是如果使用了这两个
    特性,则需要将这两个配置提供的功能切入进去,所以必须使用动态代理的方式将包含两个特性所对应的逻辑拦截增强器设置进去,这样才可以保证在调用方法
    的时候会被相应的拦截器增强,返回值为包含拦截器的代理实例

    7.2记录创建bean的ObjectFactory

    org.springframework.beans.factory.support包下的AbstractAutowireCapableBeanFactory类中的doCreateBean()方法中有这样一段代码,作者书中写错了!

     1 boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
     2         isSingletonCurrentlyInCreation(beanName));
     3 if (earlySingletonExposure) {
     4     if (logger.isDebugEnabled()) {
     5         logger.debug("Eagerly caching bean '" + beanName +
     6                 "' to allow for resolving potential circular references");
     7     }
     8     //为避免后期循环依赖,可以在bean初始化完成前将创建实例的ObjectFactory加入工厂
     9     addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
    10 }

    这一个小内容是来解释spring中处理依赖的方法的,我真的不想去记录了,哈,解释一下代码
    (1)earlySingletonExposure,字面意思是提早曝光,哪些条件可以影响这个值呢?
    (2)mbd.isSingleton():此RootBeanDefinition代表的是是否是单例
    (3)this.allowCircularReferences:是否允许循环依赖
    (4)isSingletonCurrentlyInCreation(beanName):该bean是否在创建中

    看一下代码中getEarlyBeanReference(beanName, mbd, bean)方法
    org.springframework.beans.factory.support包下的AbstractAutowireCapableBeanFactory类中

     1 /**
     2  * Obtain a reference for early access to the specified bean,
     3  * typically for the purpose of resolving a circular reference.
     4  * @param beanName the name of the bean (for error handling purposes)
     5  * @param mbd the merged bean definition for the bean
     6  * @param bean the raw bean instance
     7  * @return the object to expose as bean reference
     8  */
     9 protected Object getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean) {
    10     Object exposedObject = bean;
    11     if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
    12         for (BeanPostProcessor bp : getBeanPostProcessors()) {
    13             if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
    14                 SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp;
    15                 exposedObject = ibp.getEarlyBeanReference(exposedObject, beanName);
    16             }
    17         }
    18     }
    19     return exposedObject;
    20 }

    在getEarlyBeanReference()方法中,没有太多的逻辑处理,除了后处理器的调用时,没有别的处理工作,根据以上分析,基本可以清理spring处理循环依赖
    的解决办法,在B中创建依赖A时通过ObjectFactory提供的实例方法来判断A中的属性填充,使B中持有A仅仅是刚刚初始化并没有填充任何属性A,而这正初始化
    A的步骤还是最开始创建A的时候进行的,但是因为A和B中的A所表示的属性地址是一样的,所以在A中创建好的属性填充自然可以通过B中的A获取,这样就解决了循环
    依赖问题

    7.3 属性注入

    属性注入的功能,主要是使用的populateBean()方法,看一下属性是如何注入
    org.springframework.beans.factory.support包下的AbstractAutowireCapableBeanFactory类中

     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 protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
     9     if (bw == null) {
    10         if (mbd.hasPropertyValues()) {
    11             throw new BeanCreationException(
    12                     mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
    13         }
    14         else {
    15             // Skip property population phase for null instance.
    16             // 没有可以填充的属性
    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     // 给InstantiationAwareBeanPostProcessors最后一次机会在属性设置前改变bean
    25     // 例如:可以用来支撑属性注入的类型
    26     boolean continueWithPropertyPopulation = true;
    27 
    28     if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
    29         for (BeanPostProcessor bp : getBeanPostProcessors()) {
    30             if (bp instanceof InstantiationAwareBeanPostProcessor) {
    31                 InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
    32                 // 返回值是否继续填充bean
    33                 if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
    34                     continueWithPropertyPopulation = false;
    35                     break;
    36                 }
    37             }
    38         }
    39     }
    40 
    41     // 如果后处理器发出停止填充命令则终止后续的执行
    42     if (!continueWithPropertyPopulation) {
    43         return;
    44     }
    45 
    46     PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);
    47 
    48     if (mbd.getResolvedAutowireMode() == AUTOWIRE_BY_NAME || mbd.getResolvedAutowireMode() == AUTOWIRE_BY_TYPE) {
    49         MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
    50         // Add property values based on autowire by name if applicable.
    51         // 根据名称自动注入
    52         if (mbd.getResolvedAutowireMode() == AUTOWIRE_BY_NAME) {
    53             autowireByName(beanName, mbd, bw, newPvs);
    54         }
    55         // Add property values based on autowire by type if applicable.
    56         // 根据类型自动注入
    57         if (mbd.getResolvedAutowireMode() == AUTOWIRE_BY_TYPE) {
    58             autowireByType(beanName, mbd, bw, newPvs);
    59         }
    60         pvs = newPvs;
    61     }
    62 
    63     // 后处理器已经初始化
    64     boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
    65     // 需要依赖检查
    66     boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);
    67 
    68     if (hasInstAwareBpps || needsDepCheck) {
    69         if (pvs == null) {
    70             pvs = mbd.getPropertyValues();
    71         }
    72         PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
    73         if (hasInstAwareBpps) {
    74             for (BeanPostProcessor bp : getBeanPostProcessors()) {
    75                 if (bp instanceof InstantiationAwareBeanPostProcessor) {
    76                     InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
    77                     // 对所有需要依赖的属性进行后处理
    78                     pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
    79                     if (pvs == null) {
    80                         return;
    81                     }
    82                 }
    83             }
    84         }
    85         if (needsDepCheck) {
    86             // 依赖检查,对应depend-on属性 spring3.0废弃
    87             checkDependencies(beanName, mbd, filteredPds, pvs);
    88         }
    89     }
    90 
    91     if (pvs != null) {
    92         // 将属性应用到bean中
    93         applyPropertyValues(beanName, mbd, bw, pvs);
    94     }
    95 }

    在这个处理方法中populateBean,主要处理流程是这样的:
    (1)InstantiationAwareBeanPostProcessor处理器的postProcessAfterInstantiation来控制是否进行属性的填充
    (2)根据注入类型(byName/byType),提取依赖的bean,并统一存入PropertyValues
    (3)应用InstantiationAwareBeanPostProcessor处理器的postProcessPropertyValues方法,对属性获取完毕填充前对属性再次处理,典型应用是
    org.springframework.beans.factory.annotation包下的RequiredAnnotationBeanPostProcessor
    (4)将所有的PropertyValues中的属性填充至BeanWrapper中

    其中的有几个方法来看一下源码:
    1、根据名称依赖注入 autowireByName
    org.springframework.beans.factory.support包下的AbstractAutowireCapableBeanFactory类中

     1 /**
     2  * Fill in any missing property values with references to
     3  * other beans in this factory if autowire is set to "byName".
     4  * @param beanName the name of the bean we're wiring up.
     5  * Useful for debugging messages; not used functionally.
     6  * @param mbd bean definition to update through autowiring
     7  * @param bw the BeanWrapper from which we can obtain information about the bean
     8  * @param pvs the PropertyValues to register wired objects with
     9  */
    10 protected void autowireByName(
    11         String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {
    12 
    13     // 在bw中寻找需要依赖注入的属性
    14     String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);
    15     for (String propertyName : propertyNames) {
    16         if (containsBean(propertyName)) {
    17             // 递归初始化相关的bean
    18             Object bean = getBean(propertyName);
    19             pvs.add(propertyName, bean);
    20             // 注册依赖
    21             registerDependentBean(propertyName, beanName);
    22             if (logger.isDebugEnabled()) {
    23                 logger.debug("Added autowiring by name from bean name '" + beanName +
    24                         "' via property '" + propertyName + "' to bean named '" + propertyName + "'");
    25             }
    26         }
    27         else {
    28             if (logger.isTraceEnabled()) {
    29                 logger.trace("Not autowiring property '" + propertyName + "' of bean '" + beanName +
    30                         "' by name: no matching bean found");
    31             }
    32         }
    33     }
    34 }

    如果之前了解过autowire的使用方法,我也没有理解清楚这段代码,传入的参数pvs中找到已经加载的bean,并且递归实例化,进而加入到pvs中

    2、根据类型自动注入 autowireByType
    autowireByType和autowireByName对于我们理解与使用来说,复杂程度不会太困难,但是其实现功能的复杂程度完全不一样

     1 /**
     2  * Abstract method defining "autowire by type" (bean properties by type) behavior.
     3  * <p>This is like PicoContainer default, in which there must be exactly one bean
     4  * of the property type in the bean factory. This makes bean factories simple to
     5  * configure for small namespaces, but doesn't work as well as standard Spring
     6  * behavior for bigger applications.
     7  * @param beanName the name of the bean to autowire by type
     8  * @param mbd the merged bean definition to update through autowiring
     9  * @param bw the BeanWrapper from which we can obtain information about the bean
    10  * @param pvs the PropertyValues to register wired objects with
    11  */
    12 protected void autowireByType(
    13         String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {
    14 
    15     TypeConverter converter = getCustomTypeConverter();
    16     if (converter == null) {
    17         converter = bw;
    18     }
    19 
    20     Set<String> autowiredBeanNames = new LinkedHashSet<>(4);
    21     // 寻找bw中需要依赖注入的属性
    22     String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);
    23     for (String propertyName : propertyNames) {
    24         try {
    25             PropertyDescriptor pd = bw.getPropertyDescriptor(propertyName);
    26             // Don't try autowiring by type for type Object: never makes sense,
    27             // even if it technically is a unsatisfied, non-simple property.
    28             if (Object.class != pd.getPropertyType()) {
    29                 // 探测指定属性的set方法
    30                 MethodParameter methodParam = BeanUtils.getWriteMethodParameter(pd);
    31                 // Do not allow eager init for type matching in case of a prioritized post-processor.
    32                 boolean eager = !PriorityOrdered.class.isInstance(bw.getWrappedInstance());
    33                 
    34                 DependencyDescriptor desc = new AutowireByTypeDependencyDescriptor(methodParam, eager);
    35                 // 解析指定beanName的属性所匹配的值,并把解析到的属性名称存储在autowiredBeanNames中
    36                 // 当属性存在多个封装bean时,如:@Autowire private List<A> aList; 将会找到所有匹配的A类型的bean
    37                 // 并将其注入
    38                 Object autowiredArgument = resolveDependency(desc, beanName, autowiredBeanNames, converter);
    39                 if (autowiredArgument != null) {
    40                     pvs.add(propertyName, autowiredArgument);
    41                 }
    42                 for (String autowiredBeanName : autowiredBeanNames) {
    43                     // 注册依赖
    44                     registerDependentBean(autowiredBeanName, beanName);
    45                     if (logger.isDebugEnabled()) {
    46                         logger.debug("Autowiring by type from bean name '" + beanName + "' via property '" +
    47                                 propertyName + "' to bean named '" + autowiredBeanName + "'");
    48                     }
    49                 }
    50                 autowiredBeanNames.clear();
    51             }
    52         }
    53         catch (BeansException ex) {
    54             throw new UnsatisfiedDependencyException(mbd.getResourceDescription(), beanName, propertyName, ex);
    55         }
    56     }
    57 }

    这里面 复杂的地方是spring中提供了对集合类型的注入支持,
    @Autowire
    private List<Test> tests;
    spring会将所有Test类型的找出来并注入到tests属性中,正式由于这一因素,所以在autowireByType函数中,新建了局部遍历autowiredBeanNames,用于
    存储所有依赖的bean,如果只是对非集合类的属性注入来说,此属性并没用处
    对于寻找类型匹配的逻辑实现封装在了resolveDependency函数中:
    org.springframework.beans.factory.support包下DefaultListableBeanFactory类中

     1 @Override
     2 @Nullable
     3 public Object resolveDependency(DependencyDescriptor descriptor, @Nullable String requestingBeanName,
     4         @Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException {
     5 
     6     descriptor.initParameterNameDiscovery(getParameterNameDiscoverer());
     7     if (Optional.class == descriptor.getDependencyType()) {
     8         // Optional类注入的特殊处理
     9         return createOptionalDependency(descriptor, requestingBeanName);
    10     }
    11     else if (ObjectFactory.class == descriptor.getDependencyType() ||
    12             ObjectProvider.class == descriptor.getDependencyType()) {
    13         // ObjectFactory类注入的特殊处理
    14         return new DependencyObjectProvider(descriptor, requestingBeanName);
    15     }
    16     else if (javaxInjectProviderClass == descriptor.getDependencyType()) {
    17         // javaxInjectProviderClass类注入的特殊处理
    18         return new Jsr330ProviderFactory().createDependencyProvider(descriptor, requestingBeanName);
    19     }
    20     else {
    21         Object result = getAutowireCandidateResolver().getLazyResolutionProxyIfNecessary(
    22                 descriptor, requestingBeanName);
    23         if (result == null) {
    24             // 通用处理逻辑
    25             result = doResolveDependency(descriptor, requestingBeanName, autowiredBeanNames, typeConverter);
    26         }
    27         return result;
    28     }
    29 }

    org.springframework.beans.factory.support包下DefaultListableBeanFactory类中doResolveDependency函数,看一下通用处理的逻辑

     1 @Nullable
     2 public Object doResolveDependency(DependencyDescriptor descriptor, @Nullable String beanName,
     3         @Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException {
     4 
     5     InjectionPoint previousInjectionPoint = ConstructorResolver.setCurrentInjectionPoint(descriptor);
     6     try {
     7         Object shortcut = descriptor.resolveShortcut(this);
     8         if (shortcut != null) {
     9             return shortcut;
    10         }
    11 
    12         Class<?> type = descriptor.getDependencyType();
    13         // 用于支持spring中新增的注解@value
    14         Object value = getAutowireCandidateResolver().getSuggestedValue(descriptor);
    15         if (value != null) {
    16             if (value instanceof String) {
    17                 String strVal = resolveEmbeddedValue((String) value);
    18                 BeanDefinition bd = (beanName != null && containsBean(beanName) ? getMergedBeanDefinition(beanName) : null);
    19                 value = evaluateBeanDefinitionString(strVal, bd);
    20             }
    21             TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter());
    22             return (descriptor.getField() != null ?
    23                     converter.convertIfNecessary(value, type, descriptor.getField()) :
    24                     converter.convertIfNecessary(value, type, descriptor.getMethodParameter()));
    25         }
    26 
    27         // 如果解析器没有成功解析,则需要考虑各种情况
    28         // 这个处理逻辑实在resolveMultipleBeans函数中,现在这个版本的spring把这部分单独写成一个函数了
    29         Object multipleBeans = resolveMultipleBeans(descriptor, beanName, autowiredBeanNames, typeConverter);
    30         if (multipleBeans != null) {
    31             return multipleBeans;
    32         }
    33 
    34         Map<String, Object> matchingBeans = findAutowireCandidates(beanName, type, descriptor);
    35         if (matchingBeans.isEmpty()) {
    36             if (isRequired(descriptor)) {
    37                 raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);
    38             }
    39             return null;
    40         }
    41 
    42         String autowiredBeanName;
    43         Object instanceCandidate;
    44 
    45         if (matchingBeans.size() > 1) {
    46             autowiredBeanName = determineAutowireCandidate(matchingBeans, descriptor);
    47             if (autowiredBeanName == null) {
    48                 if (isRequired(descriptor) || !indicatesMultipleBeans(type)) {
    49                     return descriptor.resolveNotUnique(type, matchingBeans);
    50                 }
    51                 else {
    52                     // In case of an optional Collection/Map, silently ignore a non-unique case:
    53                     // possibly it was meant to be an empty collection of multiple regular beans
    54                     // (before 4.3 in particular when we didn't even look for collection beans).
    55                     // 在可选的Collection / Map的情况下,静默地忽略一个非唯一的情况:可能它是一个多个常规bean的空集合
    56                     return null;
    57                 }
    58             }
    59             instanceCandidate = matchingBeans.get(autowiredBeanName);
    60         }
    61         else {
    62             // We have exactly one match.
    63             // 已经确定只有一个匹配项
    64             Map.Entry<String, Object> entry = matchingBeans.entrySet().iterator().next();
    65             autowiredBeanName = entry.getKey();
    66             instanceCandidate = entry.getValue();
    67         }
    68 
    69         if (autowiredBeanNames != null) {
    70             autowiredBeanNames.add(autowiredBeanName);
    71         }
    72         if (instanceCandidate instanceof Class) {
    73             instanceCandidate = descriptor.resolveCandidate(autowiredBeanName, type, this);
    74         }
    75         Object result = instanceCandidate;
    76         if (result instanceof NullBean) {
    77             if (isRequired(descriptor)) {
    78                 raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);
    79             }
    80             result = null;
    81         }
    82         if (!ClassUtils.isAssignableValue(type, result)) {
    83             throw new BeanNotOfRequiredTypeException(autowiredBeanName, type, instanceCandidate.getClass());
    84         }
    85         return result;
    86     }
    87     finally {
    88         ConstructorResolver.setCurrentInjectionPoint(previousInjectionPoint);
    89     }
    90 }

    看一下resolveMultipleBeans函数的处理逻辑,在解析器没有解析成功的时候,spring如何处理
    org.springframework.beans.factory.support包下DefaultListableBeanFactory类中,同一个类中

     1 @Nullable
     2 private Object resolveMultipleBeans(DependencyDescriptor descriptor, @Nullable String beanName,
     3         @Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) {
     4 
     5     Class<?> type = descriptor.getDependencyType();
     6     // 属性是数组类型
     7     if (type.isArray()) {
     8         Class<?> componentType = type.getComponentType();
     9         // 根据属性类型找到beanFactory中所有类型匹配bean,返回值的构成为:
    10         // key=匹配的beanName value=beanName对应的实例化后的bean(通过getBean(beanName)返回)
    11         ResolvableType resolvableType = descriptor.getResolvableType();
    12         Class<?> resolvedArrayType = resolvableType.resolve();
    13         if (resolvedArrayType != null && resolvedArrayType != type) {
    14             type = resolvedArrayType;
    15             componentType = resolvableType.getComponentType().resolve();
    16         }
    17         if (componentType == null) {
    18             return null;
    19         }
    20         Map<String, Object> matchingBeans = findAutowireCandidates(beanName, componentType,
    21                 new MultiElementDescriptor(descriptor));
    22         if (matchingBeans.isEmpty()) {
    23             // 如果autowire属性为true而找到的匹配项却为空,则返回null
    24             return null;
    25         }
    26         if (autowiredBeanNames != null) {
    27             autowiredBeanNames.addAll(matchingBeans.keySet());
    28         }
    29         TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter());
    30         // 通过转换器将bean的值转换成对应的type类型
    31         Object result = converter.convertIfNecessary(matchingBeans.values(), type);
    32         if (getDependencyComparator() != null && result instanceof Object[]) {
    33             Arrays.sort((Object[]) result, adaptDependencyComparator(matchingBeans));
    34         }
    35         return result;
    36     }
    37     // 属性是Collection类型
    38     else if (Collection.class.isAssignableFrom(type) && type.isInterface()) {
    39         Class<?> elementType = descriptor.getResolvableType().asCollection().resolveGeneric();
    40         if (elementType == null) {
    41             return null;
    42         }
    43         Map<String, Object> matchingBeans = findAutowireCandidates(beanName, elementType,
    44                 new MultiElementDescriptor(descriptor));
    45         if (matchingBeans.isEmpty()) {
    46             return null;
    47         }
    48         if (autowiredBeanNames != null) {
    49             autowiredBeanNames.addAll(matchingBeans.keySet());
    50         }
    51         TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter());
    52         Object result = converter.convertIfNecessary(matchingBeans.values(), type);
    53         if (getDependencyComparator() != null && result instanceof List) {
    54             ((List<?>) result).sort(adaptDependencyComparator(matchingBeans));
    55         }
    56         return result;
    57     }
    58     // 属性是Map类型
    59     else if (Map.class == type) {
    60         ResolvableType mapType = descriptor.getResolvableType().asMap();
    61         Class<?> keyType = mapType.resolveGeneric(0);
    62         if (String.class != keyType) {
    63             return null;
    64         }
    65         Class<?> valueType = mapType.resolveGeneric(1);
    66         if (valueType == null) {
    67             return null;
    68         }
    69         Map<String, Object> matchingBeans = findAutowireCandidates(beanName, valueType,
    70                 new MultiElementDescriptor(descriptor));
    71         if (matchingBeans.isEmpty()) {
    72             return null;
    73         }
    74         if (autowiredBeanNames != null) {
    75             autowiredBeanNames.addAll(matchingBeans.keySet());
    76         }
    77         return matchingBeans;
    78     }
    79     else {
    80         return null;
    81     }
    82 }

    3、applyPropertyValues
    程序运行到这里,已经完成了对所有注入属性的获取,但是获取的属性是以PropertyValues形式存在的,还并没有应用到已经实例化的bean中,这一工作在
    applyPropertyValues函数中实现,org.springframework.beans.factory.support包下的AbstractAutowireCapableBeanFactory类中

      1 /**
      2  * Apply the given property values, resolving any runtime references
      3  * to other beans in this bean factory. Must use deep copy, so we
      4  * don't permanently modify this property.
      5  * @param beanName the bean name passed for better exception information
      6  * @param mbd the merged bean definition
      7  * @param bw the BeanWrapper wrapping the target object
      8  * @param pvs the new property values
      9  */
     10 protected void applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs) {
     11     if (pvs.isEmpty()) {
     12         return;
     13     }
     14 
     15     // 系统验证
     16     if (System.getSecurityManager() != null && bw instanceof BeanWrapperImpl) {
     17         ((BeanWrapperImpl) bw).setSecurityContext(getAccessControlContext());
     18     }
     19 
     20     MutablePropertyValues mpvs = null;
     21     List<PropertyValue> original;
     22 
     23     if (pvs instanceof MutablePropertyValues) {
     24         mpvs = (MutablePropertyValues) pvs;
     25         // 如果mpvs中的值已经被转换为对应的类型,那么可以直接设置到BeanWrapper中
     26         if (mpvs.isConverted()) {
     27             // Shortcut: use the pre-converted values as-is.
     28             try {
     29                 bw.setPropertyValues(mpvs);
     30                 return;
     31             }
     32             catch (BeansException ex) {
     33                 throw new BeanCreationException(
     34                         mbd.getResourceDescription(), beanName, "Error setting property values", ex);
     35             }
     36         }
     37         original = mpvs.getPropertyValueList();
     38     }
     39     else {
     40         // 如果pvs并不使用MutablePropertyValues封装的类型,那么直接使用原始的属性获取方法
     41         original = Arrays.asList(pvs.getPropertyValues());
     42     }
     43 
     44     TypeConverter converter = getCustomTypeConverter();
     45     if (converter == null) {
     46         converter = bw;
     47     }
     48     // 获取对应的解析器
     49     BeanDefinitionValueResolver valueResolver = new BeanDefinitionValueResolver(this, beanName, mbd, converter);
     50 
     51     // Create a deep copy, resolving any references for values.
     52     List<PropertyValue> deepCopy = new ArrayList<>(original.size());
     53     boolean resolveNecessary = false;
     54     // 遍历属性,将属性转换为对应类的对应属性类型
     55     for (PropertyValue pv : original) {
     56         if (pv.isConverted()) {
     57             deepCopy.add(pv);
     58         }
     59         else {
     60             String propertyName = pv.getName();
     61             Object originalValue = pv.getValue();
     62             Object resolvedValue = valueResolver.resolveValueIfNecessary(pv, originalValue);
     63             Object convertedValue = resolvedValue;
     64             boolean convertible = bw.isWritableProperty(propertyName) &&
     65                     !PropertyAccessorUtils.isNestedOrIndexedProperty(propertyName);
     66             if (convertible) {
     67                 convertedValue = convertForProperty(resolvedValue, propertyName, bw, converter);
     68             }
     69             // Possibly store converted value in merged bean definition,
     70             // in order to avoid re-conversion for every created bean instance.
     71             if (resolvedValue == originalValue) {
     72                 if (convertible) {
     73                     pv.setConvertedValue(convertedValue);
     74                 }
     75                 deepCopy.add(pv);
     76             }
     77             else if (convertible && originalValue instanceof TypedStringValue &&
     78                     !((TypedStringValue) originalValue).isDynamic() &&
     79                     !(convertedValue instanceof Collection || ObjectUtils.isArray(convertedValue))) {
     80                 pv.setConvertedValue(convertedValue);
     81                 deepCopy.add(pv);
     82             }
     83             else {
     84                 resolveNecessary = true;
     85                 deepCopy.add(new PropertyValue(pv, convertedValue));
     86             }
     87         }
     88     }
     89     if (mpvs != null && !resolveNecessary) {
     90         mpvs.setConverted();
     91     }
     92 
     93     // Set our (possibly massaged) deep copy.
     94     try {
     95         // BeanWrapper中 wrapper的意思是包装纸的意思 这里大概就是bean的封装类
     96         bw.setPropertyValues(new MutablePropertyValues(deepCopy));
     97     }
     98     catch (BeansException ex) {
     99         throw new BeanCreationException(
    100                 mbd.getResourceDescription(), beanName, "Error setting property values", ex);
    101     }
    102 }
  • 相关阅读:
    关于阿里云centos 2.6下手机表情输入后无法保存到mysql数据库的问题调研及mysql版本从5.1升级到5.7的全过程纪要
    EXTJS 5 学习笔记2
    EXTJS 5 学习笔记1
    关于java.lang.String理解中的一些难点
    关于centos7中使用rpm方式安装mysql5.7版本后无法使用root登录的问题
    大数据专栏
    过采样中用到的SMOTE算法
    linux后台执行命令:&和nohup
    P,R,F1 等性能度量(二分类、多分类)
    word2vec模型cbow与skip-gram的比较
  • 原文地址:https://www.cnblogs.com/ssh-html/p/11218336.html
Copyright © 2020-2023  润新知