zoukankan      html  css  js  c++  java
  • 【spring源码分析】IOC容器初始化(六)

    前言:经过前几篇文章的讲解,我们已经得到了BeanDefinition,接下来将分析Bean的加载。


    获取Bean的入口:AbstractApplicationContext#getBean

    1     public Object getBean(String name) throws BeansException {
    2         // 检测bean工厂是否存活
    3         assertBeanFactoryActive();
    4         return getBeanFactory().getBean(name);
    5     }

    分析:
    首先检查BeanFactory是否存活,还记得之前分析过的
    prepareRefresh()方法吗?如果不记得了,请翻看之前的文章,那里设置了active的值,然后在这里做检查。如果BeanFactory关闭,则抛出异常。

    1     protected void assertBeanFactoryActive() {
    2         if (!this.active.get()) {
    3             if (this.closed.get()) {
    4                 throw new IllegalStateException(getDisplayName() + " has been closed already");
    5             } else {
    6                 throw new IllegalStateException(getDisplayName() + " has not been refreshed yet");
    7             }
    8         }
    9     }

    AbstractBeanFactory#getBean

    1 @Override
    2     public Object getBean(String name) throws BeansException {
    3         return doGetBean(name, null, null, false);
    4     }

    最终切入点:

      1 // AbstractBeanFactory
      2 protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
      3                               @Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {
      4 
      5         // 返回bean名称,剥离工厂引用前缀
      6         // 如果name是alias,则获取对应映射的beanName
      7         final String beanName = transformedBeanName(name);
      8         Object bean;
      9 
     10         // 从缓存或实例工厂中获取Bean对象
     11         // Eagerly check singleton cache for manually registered singletons.
     12         Object sharedInstance = getSingleton(beanName);
     13         if (sharedInstance != null && args == null) {
     14             if (logger.isTraceEnabled()) {
     15                 if (isSingletonCurrentlyInCreation(beanName)) {
     16                     logger.trace("Returning eagerly cached instance of singleton bean '" + beanName +
     17                                          "' that is not fully initialized yet - a consequence of a circular reference");
     18                 } else {
     19                     logger.trace("Returning cached instance of singleton bean '" + beanName + "'");
     20                 }
     21             }
     22             // 完成FactoryBean的相关处理,并用来获取FactoryBean的处理结果
     23             bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
     24         } else {
     25             // Fail if we're already creating this bean instance:
     26             // We're assumably within a circular reference.
     27             // Spring只能解决单例模式下的循环依赖,在原型模式下如果存在循环依赖则抛出异常
     28             // 这里检测原型模式下,该bean是否在加载,如果在加载则抛出异常
     29             if (isPrototypeCurrentlyInCreation(beanName)) {
     30                 throw new BeanCurrentlyInCreationException(beanName);
     31             }
     32 
     33             // 如果当前容器中没有找到,则从父类容器中加载
     34             // Check if bean definition exists in this factory.
     35             BeanFactory parentBeanFactory = getParentBeanFactory();
     36             /**
     37              * 调用{@link DefaultListableBeanFactory#containsBeanDefinition(String)}方法
     38              * 其实就是在beanDefinitionMap中判断是否存在beanName对应的BeanDefinition
     39              */
     40             if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
     41                 // Not found -> check parent.
     42                 // 确定原始的beanName
     43                 String nameToLookup = originalBeanName(name);
     44                 // 如果父类容器为AbstractBeanFactory,则委托父类处理
     45                 if (parentBeanFactory instanceof AbstractBeanFactory) {
     46                     return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
     47                             nameToLookup, requiredType, args, typeCheckOnly);
     48                 } else if (args != null) { // 用明确的args从parentBeanFactory中,获取Bean对象
     49                     // Delegation to parent with explicit args.
     50                     // 委托给父类构造函数getBean()处理
     51                     return (T) parentBeanFactory.getBean(nameToLookup, args);
     52                 } else if (requiredType != null) { // 用明确的requiredType从parentBeanFactory中,获取Bean对象
     53                     // No args -> delegate to standard getBean method.
     54                     // 没有args,委托给标准的getBean()处理
     55                     return parentBeanFactory.getBean(nameToLookup, requiredType);
     56                 } else {
     57                     // 直接使用nameToLookup从parentBeanFactory中获取Bean对象
     58                     return (T) parentBeanFactory.getBean(nameToLookup);
     59                 }
     60             }
     61 
     62             // 如果不仅仅是做类型检查,而是创建bean,这里需要记录
     63             if (!typeCheckOnly) {
     64                 markBeanAsCreated(beanName);
     65             }
     66 
     67             try {
     68                 /**
     69                  * 从容器中获取beanName对应的GenericBeanDefinition对象,并转换成RootBeanDefinition对象
     70                  * GenericBeanDefinition的创建{@link BeanDefinitionReaderUtils#createBeanDefinition}方法
     71                  */
     72                 final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
     73                 // 检查合并的BeanDefinition
     74                 checkMergedBeanDefinition(mbd, beanName, args);
     75 
     76                 // Guarantee initialization of beans that the current bean depends on.
     77                 // 处理所依赖的bean
     78                 String[] dependsOn = mbd.getDependsOn();
     79                 if (dependsOn != null) {
     80                     for (String dep : dependsOn) {
     81                         // 若给定的依赖bean已经注册为依赖给定的bean
     82                         // 即循环依赖情况,抛出BeanCreationException异常
     83                         if (isDependent(beanName, dep)) {
     84                             throw new BeanCreationException(mbd.getResourceDescription(), beanName,
     85                                                             "Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
     86                         }
     87                         // 缓存依赖调用
     88                         registerDependentBean(dep, beanName);
     89                         try {
     90                             // 递归处理依赖 Bean
     91                             getBean(dep);
     92                         } catch (NoSuchBeanDefinitionException ex) {
     93                             throw new BeanCreationException(mbd.getResourceDescription(), beanName,
     94                                                             "'" + beanName + "' depends on missing bean '" + dep + "'", ex);
     95                         }
     96                     }
     97                 }
     98                 // bean实例化
     99                 // Create bean instance.
    100                 // 单例模式
    101                 /**
    102                  * 这里有个已创建bean的重要方法createBean
    103                  * {@link AbstractAutowireCapableBeanFactory#createBean(String, RootBeanDefinition, Object[])}
    104                  */
    105                 if (mbd.isSingleton()) {
    106                     sharedInstance = getSingleton(beanName, () -> {
    107                         try {
    108                             return createBean(beanName, mbd, args);
    109                         } catch (BeansException ex) {
    110                             // Explicitly remove instance from singleton cache: It might have been put there
    111                             // eagerly by the creation process, to allow for circular reference resolution.
    112                             // Also remove any beans that received a temporary reference to the bean.
    113                             // 显式从单例缓存中删除Bean实例
    114                             // 因为单例模式下为了解决循环依赖,可能它已经存在,所以销毁它
    115                             destroySingleton(beanName);
    116                             throw ex;
    117                         }
    118                     });
    119                     bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
    120                 } else if (mbd.isPrototype()) { // 原型模式
    121                     // It's a prototype -> create a new instance.
    122                     Object prototypeInstance = null;
    123                     try {
    124                         // 前置处理
    125                         beforePrototypeCreation(beanName);
    126                         /**
    127                          * 创建bean {@link AbstractAutowireCapableBeanFactory#createBean}
    128                          */
    129                         prototypeInstance = createBean(beanName, mbd, args);
    130                     } finally {
    131                         /**
    132                          * 后置处理 与前置处理相反从{@link prototypesCurrentlyInCreation}中移除
    133                          */
    134                         afterPrototypeCreation(beanName);
    135                     }
    136                     bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
    137                 } else { //其他作用域
    138                     // 获得scopeName对应的Scope对象
    139                     String scopeName = mbd.getScope();
    140                     final Scope scope = this.scopes.get(scopeName);
    141                     if (scope == null) {
    142                         throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
    143                     }
    144                     try {
    145                         /**
    146                          * 从指定的scope下创建bean
    147                          * {@link SimpleThreadScope#get方法}
    148                          */
    149                         Object scopedInstance = scope.get(beanName, () -> {
    150                             beforePrototypeCreation(beanName);
    151                             try {
    152                                 return createBean(beanName, mbd, args);
    153                             } finally {
    154                                 afterPrototypeCreation(beanName);
    155                             }
    156                         });
    157                         bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
    158                     } catch (IllegalStateException ex) {
    159                         throw new BeanCreationException(beanName,
    160                                                         "Scope '" + scopeName + "' is not active for the current thread; consider " +
    161                                                                 "defining a scoped proxy for this bean if you intend to refer to it from a singleton",
    162                                                         ex);
    163                     }
    164                 }
    165             } catch (BeansException ex) {
    166                 cleanupAfterBeanCreationFailure(beanName);
    167                 throw ex;
    168             }
    169         }
    170 
    171         // 检查需要的类型是否符合bean的实际类型
    172         // Check if required type matches the type of the actual bean instance.
    173         if (requiredType != null && !requiredType.isInstance(bean)) {
    174             try {
    175                 T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType);
    176                 if (convertedBean == null) {
    177                     throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
    178                 }
    179                 return convertedBean;
    180             } catch (TypeMismatchException ex) {
    181                 if (logger.isTraceEnabled()) {
    182                     logger.trace("Failed to convert bean '" + name + "' to required type '" +
    183                                          ClassUtils.getQualifiedName(requiredType) + "'", ex);
    184                 }
    185                 throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
    186             }
    187         }
    188         return (T) bean;
    189     }

    分析:

    这里的代码稍微有点多,但是这段代码非常重要,我们一步步来进行分析。

    AbstractBeanFactory#transformedBeanName

     1 public String canonicalName(String name) {
     2         String canonicalName = name;
     3         // Handle aliasing...
     4         String resolvedName;
     5         // 循环,从aliasMap中获取最终的beanName
     6         do {
     7             resolvedName = this.aliasMap.get(canonicalName);
     8             if (resolvedName != null) {
     9                 canonicalName = resolvedName;
    10             }
    11         }
    12         while (resolvedName != null);
    13         return canonicalName;
    14     }
    15 
    16 // BeanFactoryUtils
    17 public static String transformedBeanName(String name) {
    18         Assert.notNull(name, "'name' must not be null");
    19 
    20         // 如果beanName不是以"&"开始,则直接返回
    21         if (!name.startsWith(BeanFactory.FACTORY_BEAN_PREFIX)) {
    22             return name;
    23         }
    24         // computeIfAbsent方法,分两种情况:
    25         // #1.不存在,则执行后面的lambda表达式,beanName的值就是name的值,并将结果添加到缓存。
    26         // #2.存在,则直接返回name的值。
    27         return transformedBeanNameCache.computeIfAbsent(name, beanName -> {
    28             do {
    29                 beanName = beanName.substring(BeanFactory.FACTORY_BEAN_PREFIX.length());
    30             }
    31             while (beanName.startsWith(BeanFactory.FACTORY_BEAN_PREFIX));
    32             return beanName;
    33         });
    34     }

    分析:

    transformedBeanName函数的功能:返回beanName,剥离工厂引用前缀。

    在BeanFactoryUtils#transformedBeanName中:

    • 如果beanName不是以"&"开始,则直接返回。
    • 如果transformedBeanNameCache缓存中存在已经解析好的beanName,则直接返回。
    • 不存在,则剥离"&"符号后,将beanName加入缓存,然后再返回beanName。
    • SimpleAliasRegistry#canonicalName中循环从aliasMap中获取最终的beanName。

    DefaultSingletonBeanRegistry#getSingleton

     1 protected Object getSingleton(String beanName, boolean allowEarlyReference) {
     2         // 从单例缓存中加载Bean
     3         Object singletonObject = this.singletonObjects.get(beanName);
     4         // 缓存中bean为空,且当前bean正在创建
     5         if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
     6             // 做同步
     7             synchronized (this.singletonObjects) {
     8                 // 从earlySingletonObjects集合中获取
     9                 singletonObject = this.earlySingletonObjects.get(beanName);
    10                 // earlySingletonObjects集合中没有,其允许提前创建
    11                 if (singletonObject == null && allowEarlyReference) {
    12                     // 从singletonFactories中获取对应的ObjectFactory
    13                     ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
    14                     if (singletonFactory != null) {
    15                         // 获取bean
    16                         singletonObject = singletonFactory.getObject();
    17                         // 将bean添加到earlySingletonObjects集合中
    18                         this.earlySingletonObjects.put(beanName, singletonObject);
    19                         // 从singletonFactories中移除对应的
    20                         this.singletonFactories.remove(beanName);
    21                     }
    22                 }
    23             }
    24         }
    25         return singletonObject;
    26     }

    分析:

    在加载bean时,首先从单例缓存中获取bean对象。

    • 首先从单例缓存中获取bean对象,如果缓存中存在bean对象则直接返回(单例模式的bean在创建过程中会进行缓存[singletonObjects])。
    • 如果缓存中bean对象为空,且当前bean正在创建,则从earlySingletonObjects中获取。
    • 如果earlySingletonObjects集合中不存在,且允许提前创建bean,则从singletonFactories中获取单例工厂,若singleFactory不为空,则通过getObject方法获取bean,并将bean对象加入到earlySingletonObjects集合中,然后从singleFactory集合中移除对应的单例工厂对象。

    注意这里涉及到三个集合:

    • singletonObjects (一级)单例对象 Cache
    • earlySingletonObjects (二级)提前曝光的单例对象 Cache
    • singletonFactories (三级)单例对象工厂 Cache
     1 /**
     2      * Cache of singleton objects: bean name to bean instance.
     3      * 存放的是单例 bean 的映射。
     4      * <p>
     5      * 对应关系为 bean name --> bean instance
     6      */
     7     private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);
     8 
     9     /**
    10      * Cache of singleton factories: bean name to ObjectFactory.<br/>
    11      * 存放的是 ObjectFactory,可以理解为创建单例 bean 的 factory 。
    12      * <p>
    13      * 对应关系是 bean name --> ObjectFactory
    14      */
    15     private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);
    16 
    17     /**
    18      * Cache of early singleton objects: bean name to bean instance.<br/>
    19      * 存放的是早期的 bean,对应关系也是 bean name --> bean instance。
    20      * <p>
    21      * 它与 {@link #singletonFactories} 区别在于 earlySingletonObjects 中存放的 bean 不一定是完整。
    22      * <p>
    23      * 从 {@link #getSingleton(String)} 方法中,我们可以了解,bean 在创建过程中就已经加入到 earlySingletonObjects 中了。
    24      * 所以当在 bean 的创建过程中,就可以通过 getBean() 方法获取。
    25      * <p>
    26      * 这个 Map 也是【循环依赖】的关键所在。
    27      */
    28     private final Map<String, Object> earlySingletonObjects = new HashMap<>(16);

    这三个缓存集合就是解决Spring中循环依赖的所在,具体流程:

    • 首先从一级缓存singletonObjects中获取,如果为null,且当前bean正在被创建,则从二级缓存earlySingletonObjects中获取,如果还是为null,且允许singletonFactories通过getObject获取,则从三级缓存singletonFactories中获取,如果得到,则将其加入二级缓存earlySingletonObjects中,并从三级缓存singletonFactories中移除对应的工厂对象(因为单例模式的bean只会被创建一次),这样三级缓存就升级到二级缓存了,所以二级缓存存在的意义就是缓存三级缓存中ObjectFactory#getObject的执行结果,提前曝光单例Bean对象。

    如果从单例缓存中得到bean对象,则会调用getObjectForBeanInstance方法进一步处理,因为从缓存中得到的bean是最原始的bean,并不一定是最终所需要的bean对象。

    AbstractAutowireCapableBeanFactory#getObjectForBeanInstance

     1     protected Object getObjectForBeanInstance(
     2             Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd) {
     3 
     4         String currentlyCreatedBean = this.currentlyCreatedBean.get();
     5         if (currentlyCreatedBean != null) {
     6             registerDependentBean(beanName, currentlyCreatedBean);
     7         }
     8 
     9         return super.getObjectForBeanInstance(beanInstance, name, beanName, mbd);
    10     }

    分析:

    • 首先如果bean正在被创建,则会注册依赖关系(registerDependentBean,该函数还未仔细分析,后续查漏补缺)。
    • 然后调用父类的getObjectForBeanInstance方法获取Bean对象。

    AbstractBeanFactory#getObjectForBeanInstance

     1 protected Object getObjectForBeanInstance(
     2             Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd) {
     3 
     4         // 如果name是工厂类的引用名称(name以"&"开头)
     5         // Don't let calling code try to dereference the factory if the bean isn't a factory.
     6         if (BeanFactoryUtils.isFactoryDereference(name)) {
     7             // 如果是NullBean则直接返回
     8             if (beanInstance instanceof NullBean) {
     9                 return beanInstance;
    10             }
    11             // 如果beanInstance不是FactoryBean则抛出异常
    12             if (!(beanInstance instanceof FactoryBean)) {
    13                 throw new BeanIsNotAFactoryException(transformedBeanName(name), beanInstance.getClass());
    14             }
    15         }
    16 
    17         // 走到这里,说明我们现在已经有一个Bean实例,当然该实例可能会是一个正常的Bean或者又是一个FactoryBean
    18         // 如果是FactoryBean,则创建Bean
    19         // Now we have the bean instance, which may be a normal bean or a FactoryBean.
    20         // If it's a FactoryBean, we use it to create a bean instance, unless the
    21         // caller actually wants a reference to the factory.
    22         // 如果beanInstance不是Factory或者beanName以&开头,则直接返回
    23         if (!(beanInstance instanceof FactoryBean) || BeanFactoryUtils.isFactoryDereference(name)) {
    24             return beanInstance;
    25         }
    26 
    27         Object object = null;
    28         // 若BeanDefinition为null,则从缓存中加载bean对象
    29         if (mbd == null) {
    30             object = getCachedObjectForFactoryBean(beanName);
    31         }
    32         // 如果Object仍然为空,则可以确认beanInstance一定是FactoryBean。从而使用FactoryBean获取Bean对象
    33         // 通过beanInstance instanceof FactoryBean这里判断,如果beanInstance不是FactoryBean已经直接返回了
    34         if (object == null) {
    35             // Return bean instance from factory.
    36             FactoryBean<?> factory = (FactoryBean<?>) beanInstance;
    37             // 检测beanDefinitionMap中,也就是所有已加载的类中是否定义了beanName
    38             // Caches object obtained from FactoryBean if it is a singleton.
    39             if (mbd == null && containsBeanDefinition(beanName)) {
    40                 // 将存储XML配置文件的GenericBeanDefinition转换为RootBeanDefinition
    41                 // 如果指定beanName是子Bean的话同时会合并父类的相关属性
    42                 mbd = getMergedLocalBeanDefinition(beanName);
    43             }
    44             // 是否是用户定义的,而不是程序本身定义的
    45             boolean synthetic = (mbd != null && mbd.isSynthetic());
    46             // 核心函数,使用FactoryBean获得Bean对象
    47             object = getObjectFromFactoryBean(factory, beanName, !synthetic);
    48         }
    49         return object;
    50     }

    分析:

    • 如果beanName以"&"开头,表示是工厂类的实例对象,如果beanInstance为NullBean则直接返回,如果beanInstance不为FactoryBean,则抛出异常,这里主要是校验beanInstance的正确性
    • 如果beanInstance不是FactoryBean或者beanName不以"&"开头,则直接返回beanInstance对象。这里主要是对非FactoryBean的处理
    • 如果BeanDefinition为null,则从缓存中加载bean对象,如果还是为null,则可以确定beanInstance一定是FactoryBean,具体看前面的两个判断
    • 检测beanDefinitionMap中是否已经加载了该bean,如果加载过着会判断是否需要合并父类的相关属性--getMergedLocalBeanDefinition方法。
    • 最后使用getObjectFromFactoryBean获取bean对象。

    AbstractBeanFactory#getMergedLocalBeanDefinition

     1 protected RootBeanDefinition getMergedLocalBeanDefinition(String beanName) throws BeansException {
     2         // Quick check on the concurrent map first, with minimal locking.
     3         // 快速从缓存中获取,如果不为null,则直接返回
     4         RootBeanDefinition mbd = this.mergedBeanDefinitions.get(beanName);
     5         if (mbd != null) {
     6             return mbd;
     7         }
     8         // 获取RootBeanDefinition,如果返回的BeanDefinition是子类的bean的话,则合并父类相关属性
     9         // getBeanDefinition函数从beanDefinitionMap中取出对应的BeanDefinition
    10         return getMergedBeanDefinition(beanName, getBeanDefinition(beanName));
    11     }

    分析:

    • 首先检查缓存中是否存在已经转换过的RootBeanDefinition对象,如果存在,则直接返回。
    • 通过getMergedBeanDefinition函数进行BeanDefinition的转换。

    AbstractBeanFactory#getMergedBeanDefinition

     1 protected RootBeanDefinition getMergedBeanDefinition(
     2             String beanName, BeanDefinition bd, @Nullable BeanDefinition containingBd)
     3             throws BeanDefinitionStoreException {
     4         // 做同步
     5         synchronized (this.mergedBeanDefinitions) {
     6             RootBeanDefinition mbd = null;
     7             // 如果containingBd为null,则从mergedBeanDefinitions中尝试获取
     8             // Check with full lock now in order to enforce the same merged instance.
     9             if (containingBd == null) {
    10                 mbd = this.mergedBeanDefinitions.get(beanName);
    11             }
    12             // 如果集合中不存在RootBeanDefinition
    13             if (mbd == null) {
    14                 // 并且无父类
    15                 if (bd.getParentName() == null) {
    16                     // 如果BeanDefinition是RootBeanDefinition类型,则直接拷贝
    17                     // Use copy of given root bean definition.
    18                     if (bd instanceof RootBeanDefinition) {
    19                         mbd = ((RootBeanDefinition) bd).cloneBeanDefinition();
    20                     } else {
    21                         // 否则新创建一个RootBeanDefinition对象
    22                         mbd = new RootBeanDefinition(bd);
    23                     }
    24                 } else {
    25                     // 如果存在父类
    26                     // Child bean definition: needs to be merged with parent.
    27                     BeanDefinition pbd;
    28                     try {
    29                         // 首先获取父类的beanName
    30                         String parentBeanName = transformedBeanName(bd.getParentName());
    31                         // beanName与父类beanName不相等
    32                         if (!beanName.equals(parentBeanName)) {
    33                             // 通过父类beanName返回BeanDefinition
    34                             pbd = getMergedBeanDefinition(parentBeanName);
    35                         } else {
    36                             BeanFactory parent = getParentBeanFactory();
    37                             if (parent instanceof ConfigurableBeanFactory) {
    38                                 pbd = ((ConfigurableBeanFactory) parent).getMergedBeanDefinition(parentBeanName);
    39                             } else {
    40                                 throw new NoSuchBeanDefinitionException(parentBeanName,
    41                                                                         "Parent name '" + parentBeanName + "' is equal to bean name '" + beanName +
    42                                                                                 "': cannot be resolved without an AbstractBeanFactory parent");
    43                             }
    44                         }
    45                     } catch (NoSuchBeanDefinitionException ex) {
    46                         throw new BeanDefinitionStoreException(bd.getResourceDescription(), beanName,
    47                                                                "Could not resolve parent bean definition '" + bd.getParentName() + "'", ex);
    48                     }
    49                     // Deep copy with overridden values.
    50                     mbd = new RootBeanDefinition(pbd);
    51                     mbd.overrideFrom(bd);
    52                 }
    53 
    54                 // Set default singleton scope, if not configured before.
    55                 if (!StringUtils.hasLength(mbd.getScope())) {
    56                     mbd.setScope(RootBeanDefinition.SCOPE_SINGLETON);
    57                 }
    58 
    59                 // A bean contained in a non-singleton bean cannot be a singleton itself.
    60                 // Let's correct this on the fly here, since this might be the result of
    61                 // parent-child merging for the outer bean, in which case the original inner bean
    62                 // definition will not have inherited the merged outer bean's singleton status.
    63                 if (containingBd != null && !containingBd.isSingleton() && mbd.isSingleton()) {
    64                     mbd.setScope(containingBd.getScope());
    65                 }
    66 
    67                 // Cache the merged bean definition for the time being
    68                 // (it might still get re-merged later on in order to pick up metadata changes)
    69                 if (containingBd == null && isCacheBeanMetadata()) {
    70                     this.mergedBeanDefinitions.put(beanName, mbd);
    71                 }
    72             }
    73 
    74             return mbd;
    75         }
    76     }

    分析(注意给方法是同步的,Spring中很多这种同步方法):

    • 首先从缓存中查找是否存在RootBeanDefinition,如果不存在,且当前BeanDefinition无父类,则会得到一个RootBeanDefinition对象(若BeanDefinition本身就是RootBeanDefinition,则直接拷贝,否则就实例化一个对象)。
    • 如果BeanDefinition存在父类,且父类名beanName与子类beanName不相等,则通过父类去创建BeanDefinition对象(getMergedBeanDefinition),如果beanName不相等,则通过父类工厂去创建BeanDefinition对象。
    • RootBeanDefinition对象创建好后,会设置对象的作用域,如果之前为设置,则默认为单例模式(后续的作用域设置理解得不是很清楚),最后会缓存新生成的RootBeanDefinition对象。

    FactoryBeanRegistrySupport#getObjectFromFactoryBean

     1 protected Object getObjectFromFactoryBean(FactoryBean<?> factory, String beanName, boolean shouldPostProcess) {
     2         // 为单例模式,其缓存中存在该bean实例
     3         if (factory.isSingleton() && containsSingleton(beanName)) {
     4             /**
     5              * 做同步,内部其实使用的就是{@link DefaultSingletonBeanRegistry#singletonObjects}
     6              */
     7             synchronized (getSingletonMutex()) {
     8                 // 从缓存中获取指定的factoryBean
     9                 Object object = this.factoryBeanObjectCache.get(beanName);
    10                 if (object == null) {
    11                     // 为空,则从FactoryBean中获取对象
    12                     object = doGetObjectFromFactoryBean(factory, beanName);
    13                     // Only post-process and store if not put there already during getObject() call above
    14                     // (e.g. because of circular reference processing triggered by custom getBean calls)
    15                     // 再次从缓存中获取bean对象,主要是因为循环依赖
    16                     Object alreadyThere = this.factoryBeanObjectCache.get(beanName);
    17                     if (alreadyThere != null) {
    18                         object = alreadyThere;
    19                     } else {
    20                         // 需要后续处理
    21                         if (shouldPostProcess) {
    22                             // 如果该Bean处于创建中,则返回非处理对象,而不是存储该对象
    23                             if (isSingletonCurrentlyInCreation(beanName)) {
    24                                 // Temporarily return non-post-processed object, not storing it yet..
    25                                 return object;
    26                             }
    27                             // 单例bean的前置处理 用于添加标志,当前bean正处于创建中
    28                             beforeSingletonCreation(beanName);
    29                             try {
    30                                 // 对FactoryBean获取的对象进行后置处理,返回生成的对象
    31                                 object = postProcessObjectFromFactoryBean(object, beanName);
    32                             } catch (Throwable ex) {
    33                                 throw new BeanCreationException(beanName,
    34                                                                 "Post-processing of FactoryBean's singleton object failed", ex);
    35                             } finally {
    36                                 // 单例bean的后置处理 和前置处理相反,前置添加,后置移除 移除标志,当前bean不处于创建中
    37                                 afterSingletonCreation(beanName);
    38                             }
    39                         }
    40                         // 添加到factoryBeanObjectCache中进行缓存
    41                         if (containsSingleton(beanName)) {
    42                             this.factoryBeanObjectCache.put(beanName, object);
    43                         }
    44                     }
    45                 }
    46                 return object;
    47             }
    48         } else {
    49             // 不满足第一个条件,不是单例,或者缓存中不存在,则从FactoryBean中获取对象
    50             Object object = doGetObjectFromFactoryBean(factory, beanName);
    51             // 需要后续处理
    52             if (shouldPostProcess) {
    53                 try {
    54                     // 对FactoryBean获取的对象进行后处理
    55                     // 返回生成的对象
    56                     object = postProcessObjectFromFactoryBean(object, beanName);
    57                 } catch (Throwable ex) {
    58                     throw new BeanCreationException(beanName, "Post-processing of FactoryBean's object failed", ex);
    59                 }
    60             }
    61             return object;
    62         }
    63     }

    由于篇幅原因该函数将在后续文章中继续分析,文章太长笔者认为不宜阅读。

    总结

    本文才进入加载bean的流程,从单例缓存中获取单例bean对象,后续继续强行开撸。


    by Shawn Chen,2019.04.20,上午。

  • 相关阅读:
    2020年全国安全生产月活动主题、挂图、招贴、标语、宣教用书等系列产品
    2020年安全生产月主题挂图指定宣教用品目录
    LNMP分离式部署步骤详解
    FTP文件传输服务
    DNS域名解析服务配置与测试
    DHCP服务搭建测试流程
    mysql数据库的操作
    mysql源码编译安装及其配置
    生产环境中ansible的安全处理
    http网页返回码详解
  • 原文地址:https://www.cnblogs.com/developer_chan/p/10723911.html
Copyright © 2011-2022 走看看