zoukankan      html  css  js  c++  java
  • spring源码学习(二) 小小少年

    本篇文章,来介绍finishBeanFactoryInitialization(beanFactory);这个方法主要是完成bean的实例化,

    invokeBeanFactoryPostProcessors(beanFactory);负责把所有的bean扫描到beanDefinitionMap中;

    下面来说是如何初始化的

    org.springframework.beans.factory.support.AbstractBeanFactory#doGetBean

    我们直接从这个方法开始说起,前面的调用链简单,就不说了

     1 protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
     2             @Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {
     3 
     4     /**
     5      * 通过name获取beanName,这里不使用name直接作为beanName有两个原因:
     6      *  1.name可能是以&开头的,表明调用者想获取FactoryBean本身,而非FactoryBean;在beanFactory中factoryBean的存储也是map格式
     7      *    <beanName,bean> 只是说,普通的beanName是没有&这个字符串的,所以,需要将name的首字母移除,这样才能从缓存中拿到factoryBean
     8      *  2.还是别名的问题,需要转换
     9      */
    10     final String beanName = transformedBeanName(name);
    11     Object bean;
    12 
    13     /**
    14      * 1.从单例池中获取当前bean
    15      * 2.这里是循环依赖的重要方法之一
    16      *
    17      */
    18     // Eagerly check singleton cache for manually registered singletons.
    19     Object sharedInstance = getSingleton(beanName);
    20     if (sharedInstance != null && args == null) {
    21         if (logger.isDebugEnabled()) {
    22             if (isSingletonCurrentlyInCreation(beanName)) {
    23                 logger.debug("Returning eagerly cached instance of singleton bean '" + beanName +
    24                         "' that is not fully initialized yet - a consequence of a circular reference");
    25             }
    26             else {
    27                 logger.debug("Returning cached instance of singleton bean '" + beanName + "'");
    28             }
    29         }
    30         bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
    31     }
    32 
    33     else {
    34         // Fail if we're already creating this bean instance:
    35         // We're assumably within a circular reference.
    36         /**
    37          * 这里判断bean是否在创建过程中,是第二次调用的时候 才会判断;如果是第一次执行到这里,set集合是空(这里判断的是原型bean)
    38          */
    39         if (isPrototypeCurrentlyInCreation(beanName)) {
    40             throw new BeanCurrentlyInCreationException(beanName);
    41         }
    42 
    43         //添加到alreadyCreated集合当中,表示当前bean已经创建过一次了
    44         if (!typeCheckOnly) {
    45             markBeanAsCreated(beanName);
    46         }
    47 
    48         try {
    49             final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
    50             checkMergedBeanDefinition(mbd, beanName, args);
    51 
    52             // Guarantee initialization of beans that the current bean depends on.
    53             String[] dependsOn = mbd.getDependsOn();
    54             if (dependsOn != null) {
    55                 for (String dep : dependsOn) {
    56                     if (isDependent(beanName, dep)) {
    57                         throw new BeanCreationException(mbd.getResourceDescription(), beanName,
    58                                 "Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
    59                     }
    60                     registerDependentBean(dep, beanName);
    61                     try {
    62                         getBean(dep);
    63                     }
    64                     catch (NoSuchBeanDefinitionException ex) {
    65                         throw new BeanCreationException(mbd.getResourceDescription(), beanName,
    66                                 "'" + beanName + "' depends on missing bean '" + dep + "'", ex);
    67                     }
    68                 }
    69             }
    70 
    71             // Create bean instance.如果当前bean是单实例的,就调用createBean
    72             if (mbd.isSingleton()) {
    73                 sharedInstance = getSingleton(beanName, () -> {
    74                     try {
    75                         return createBean(beanName, mbd, args);
    76                     }
    77                     catch (BeansException ex) {
    78                         // Explicitly remove instance from singleton cache: It might have been put there
    79                         // eagerly by the creation process, to allow for circular reference resolution.
    80                         // Also remove any beans that received a temporary reference to the bean.
    81                         destroySingleton(beanName);
    82                         throw ex;
    83                     }
    84                 });
    85                 bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
    86             }
    87         }
    88         catch (BeansException ex) {
    89             cleanupAfterBeanCreationFailure(beanName);
    90             throw ex;
    91         }
    92     }
    93 
    94 
    95     return (T) bean;
    96 }

    粘贴出来的方法删减了一部分代码,我们只说单实例bean的初始化;

    在判断当前bean是单实例的时候,会调用createBean;在getSingleton这里,有一行代码,是把当前bean添加到一个set集合中(这个set集合表示当前bean正在创建过程中),

    这个set是用来解决循环依赖问题的,在后面,会单独抽出一篇来介绍循环引用是如何解决的,在这里就先跳过;

    在createBean的方法中,会调用createBeanInstance(beanName, mbd, args); 这个方法主要是完成bean的初始化,在方法中会调用org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor#determineCandidateConstructors;

    这个后置处理器的determineCandidateConstructors方法来推断使用哪个构造函数来初始化;

    这个方法里面,我目前也正在学习,后续会贴出对这个方法的学习笔记,这里先暂时跳过;(我们就认为createBeanInstance方法完成了bean的创建),

    推断出使用哪个构造函数之后,会初始化bean,返回的是一个BeanWrapper对象。这里创建出来的仅仅是bean对象;需要经过后面的属性注入,以及初始化,才会变成我们所说的spring bean对象;

     1 protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
     2             throws BeanCreationException {
     3 
     4     // Instantiate the bean.
     5     BeanWrapper instanceWrapper = null;
     6     if (mbd.isSingleton()) {
     7         instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
     8     }
     9     if (instanceWrapper == null) {
    10         /**
    11          *  创建bean实例,并将bean实例包裹在BeanWrapper实现类对象中返回,
    12          *  createBeanInstance中包含三种创建bean的方式
    13          *    1.通过工厂方法创建bean实例
    14          *    2.通过构造方法自动注入的方式创建bean实例
    15          *    3.通过无参构造方法创建bean实例
    16          *
    17          *  如果bean的配置中配置了lookup-method和replace-method  则会使用增强bean实例
    18          *
    19          * 在这个方法中完成了对bean的创建(仅仅是new出来,也就是说在这个方法里面推断要使用哪个构造函数来创建bean对象)
    20          * 然后完成bean的初始化
    21          *
    22          */
    23         instanceWrapper = createBeanInstance(beanName, mbd, args);
    24     }
    25     final Object bean = instanceWrapper.getWrappedInstance();
    26     Class<?> beanType = instanceWrapper.getWrappedClass();
    27     if (beanType != NullBean.class) {
    28         mbd.resolvedTargetType = beanType;
    29     }
    30 
    31     // Allow post-processors to modify the merged bean definition.
    32     synchronized (mbd.postProcessingLock) {
    33         if (!mbd.postProcessed) {
    34             try {
    35                 //mpy 第三次调用后置处理器  缓存注解信息
    36                 applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
    37             }
    38             catch (Throwable ex) {
    39                 throw new BeanCreationException(mbd.getResourceDescription(), beanName,
    40                         "Post-processing of merged bean definition failed", ex);
    41             }
    42             mbd.postProcessed = true;
    43         }
    44     }
    45 
    46     // Eagerly cache singletons to be able to resolve circular references
    47     // even when triggered by lifecycle interfaces like BeanFactoryAware.
    48     boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
    49             isSingletonCurrentlyInCreation(beanName));
    50     if (earlySingletonExposure) {
    51         if (logger.isDebugEnabled()) {
    52             logger.debug("Eagerly caching bean '" + beanName +
    53                     "' to allow for resolving potential circular references");
    54         }
    55         //mpy 第四次调用后置处理器 获取一个提前暴露的对象  用来解决循环依赖
    56         addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
    57     }
    58 
    59     // Initialize the bean instance.
    60     Object exposedObject = bean;
    61     try {
    62         //在populateBean(beanName, mbd, instanceWrapper);方法中完成第五次第六次调用后置处理器
    63         populateBean(beanName, mbd, instanceWrapper);
    64         //在initialzeBean中完成第七次第八次后置处理器调用
    65         exposedObject = initializeBean(beanName, exposedObject, mbd);
    66     }
    67     catch (Throwable ex) {
    68         if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
    69             throw (BeanCreationException) ex;
    70         }
    71         else {
    72             throw new BeanCreationException(
    73                     mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
    74         }
    75     }
    76     return exposedObject;
    77 }

    上面这个方法中,调用第四次后置处理器这里,返回了一个object对象,这个方法是为了完成循环依赖的,放到后面一起讲,

    在populateBean中,会完成属性的注入,比如@AutoWired,@Value这个属性值注入

    initializeBean方法,主要是调用bean的初始化方法

      bean的初始化有三种方式:

       1.@Bean注解中指定 initMethod destroyMethod

       2.@PostConstruct @PreDestroy

       3.实现DisposableBean和InitializingBean接口

    在方法执行完之后,会把创建好的bean对象存放到singletonObjects这个map中,这个map存放的是所有实例化好的对象;如果bean是原型的,在第二次getBean的时候,会从这个map中获取到bean对象

    从狭义上来讲,singletonObjects就是我们所说的spring容器

  • 相关阅读:
    CF1036C Solution
    CF1041E Solution
    CF1043E Solution
    CF1054D Solution
    CF1032D Solution
    题解 P6194 【[EER1]苏联人】
    题解 CF1324A 【Yet Another Tetris Problem】
    题解 CF1325A 【EhAb AnD gCd】
    题解 CF1325B 【CopyCopyCopyCopyCopy】
    题解 AT5805 【Bishop】
  • 原文地址:https://www.cnblogs.com/mpyn/p/11784232.html
Copyright © 2011-2022 走看看