finishBeanFactoryInitialization(beanFactory);初始化剩下的所有的单实例(非懒加载)Bean(Instantiate all remaining (non-lazy-init) singletons.)

1. beanFactory.preInstantiateSingletons();初始化剩下的所有的单实例(非懒加载)Bean

  1) 首先获取所有BeanDefinition的名字List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);

  2) 根据名字获取Bean的定义信息RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);

  3) 再依次判断RootBeanDefinition不是抽象的,是单例的,不是懒加载的

    1> 判断是不是工厂Bean,isFactoryBean(beanName),如果是的话,利用工厂来创建对象

    2> 如果不是,就用getBean(beanName);来创建对象.

      0. getBean(beanName)

      1. doGetBean(name, null, null, false);

      2. 先从缓存中获取单实例Bean,如果能获取到说明这个Bean创建过(所有创建过的单实例Bean都会被缓存起来)

      Object sharedInstance = getSingleton(beanName);

      /** Cache of singleton objects: bean name --> bean instance */

      private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);

      3. 缓存中没有的话,就来创建对象.

      4. 标记当前Bean已被创建

      5. 获取Bean的定义信息

      6. 获取当前Bean依赖的其它Bean(dependsOn),如果有按照getBean()把依赖的Bean先创建出来。

      7. 启动单实例Bean的创建流程

        1)createBean(beanName,mbd,args)

        2)Object bean = resolveBeforeInstantiation(beanName, mbdToUse);让BeanPostProcessor先拦截返回代理对象

          InstantiationAwareBeanPostProcessor提前执行:

          先触发InstantiationAwareBeanPostProcessor接口中的postProcessBeforeInstantiation(beanClass, beanName);

          如果有返回值,那么再触发InstantiationAwareBeanPostProcessor中的postProcessAfterInitialization(result, beanName);

        3)如果InstantiationAwareBeanPostProcessor没有返回代理对象

        4)Object beanInstance = doCreateBean(beanName, mbdToUse, args);创建Bean

          1. 【创建Bean的实例】instanceWrapper = createBeanInstance(beanName, mbd, args);创建Bean

            利用工厂方法或者构造器来创建Bean的实例

          2. applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);

            调用MergedBeanDefinitionPostProcessor的bdp.postProcessMergedBeanDefinition(mbd, beanType, beanName);

Spring源码窥探之:单实例Bean的创建过程的更多相关文章

  1. Spring源码学习-容器BeanFactory(五) Bean的创建-探寻Bean的新生之路

    写在前面 上面四篇文章讲了Spring是如何将配置文件一步一步转化为BeanDefinition的整个流程,下面就到了正式创建Bean对象实例的环节了,我们一起继续学习吧. 2.初始化Bean对象实例 ...

  2. Spring IOC 容器源码分析 - 获取单例 bean

    1. 简介 为了写 Spring IOC 容器源码分析系列的文章,我特地写了一篇 Spring IOC 容器的导读文章.在导读一文中,我介绍了 Spring 的一些特性以及阅读 Spring 源码的一 ...

  3. Spring源码学习-容器BeanFactory(三) BeanDefinition的创建-解析Spring的默认标签

    写在前面 上文Spring源码学习-容器BeanFactory(二) BeanDefinition的创建-解析前BeanDefinition的前置操作中Spring对XML解析后创建了对应的Docum ...

  4. Spring源码学习-容器BeanFactory(四) BeanDefinition的创建-自定义标签的解析.md

    写在前面 上文Spring源码学习-容器BeanFactory(三) BeanDefinition的创建-解析Spring的默认标签对Spring默认标签的解析做了详解,在xml元素的解析中,Spri ...

  5. Spring源码学习-容器BeanFactory(二) BeanDefinition的创建-解析前BeanDefinition的前置操作

    写在前面 上文 Spring源码学习-容器BeanFactory(一) BeanDefinition的创建-解析资源文件主要讲Spring容器创建时通过XmlBeanDefinitionReader读 ...

  6. Spring源码分析(十六)准备创建bean

    本文结合<Spring源码深度解析>来分析Spring 5.0.6版本的源代码.若有描述错误之处,欢迎指正. 我们不可能指望在一个函数中完成一个复杂的逻辑,而且我们跟踪了这么多Spring ...

  7. Spring源码分析(十一)bean的加载

    摘要:本文结合<Spring源码深度解析>来分析Spring 5.0.6版本的源代码.若有描述错误之处,欢迎指正. 经过前面的分析,我们终于结束了对XML配置文件的解析,接下来将会面临更大 ...

  8. spring源码阅读笔记06:bean加载之准备创建bean

    上文中我们学习了bean加载的整个过程,我们知道从spring容器中获取单例bean时会先从缓存尝试获取,如果缓存中不存在已经加载的单例bean就需要从头开始bean的创建,而bean的创建过程是非常 ...

  9. Spring源码分析(七)bean标签的解析及注册

    摘要:本文结合<Spring源码深度解析>来分析Spring 5.0.6版本的源代码.若有描述错误之处,欢迎指正. 在上一篇中提到过Spring中的标签包括默认标签和自定义标签两种,而两种 ...

随机推荐

  1. LinkedHashSet有没有重复的元素

      1.LinkedHashSet 的概述和使用 llinkedHashSet 的特点: 是唯一能保证怎么存就怎么输出的 set 集合,并且去重复 1 LinkedHashSet<String& ...

  2. was unable to refresh its cache! status = Cannot execute request on any known server

    出现这种错误是因为: Eureka服务注册中心也会将自己作为客户端来尝试注册它自己,所以我们需要禁用它的客户端注册行为. 在 yml中设置 eureka.client.register-with-eu ...

  3. go switch 和java C#有不同

    1 switch 后的语句可以有简单的赋值语句 2 case :后的语句结束后不需要break;默认自动结束 除非以 fallthrough 语句结束,否则分支会自动终止 没有条件的 switch 有 ...

  4. Golang 常用的第三方包.

    Goland 下面这个license server 可用 http://idea.youbbs.org (2018-01-10 04:26:09) http://45.77.127.87:81(201 ...

  5. 全栈项目|小书架|服务器端-NodeJS+Koa2 实现评论功能

    评论功能分析 上图可以看出评论功能主要实现了:评论的发布.评论列表的展示. 在不考虑子评论以及图片评论的场景下,评论功能主要有以下两个接口: 发布评论 获取评论列表(考虑分页) 评论 Model 的建 ...

  6. 自学Python编程的第十一天----------来自苦逼的转行人

    2019-09-21-23:00:26 今天看了很多博客网的博客,看完觉得自己的博客真的是垃圾中的垃圾 新手不知道怎样写博客,我也很想写好一篇能让人看的博客,但是目前水平不够 只能慢慢改,今天的博客还 ...

  7. Python进阶(四)----生成器、列表推导式、生成器推导式、匿名函数和内置函数

    Python进阶(四)----生成器.列表推导式.生成器推导式.匿名函数和内置函数 一丶生成器 本质: ​ 就是迭代器 生成器产生的方式: ​ 1.生成器函数

  8. Java利用POI实现导入导出Excel表格示例代码

    转自:https://www.jb51.net/article/95526.htm 介绍 Jakarta POI 是一套用于访问微软格式文档的Java API.Jakarta POI有很多组件组成,其 ...

  9. 【WPF】EntityframeworkCore Update注意事项

    The instance of entity type 'Book' cannot be tracked because another instance with the same key valu ...

  10. Cypress自动化环境搭建

    1.Cypress 下载: 官网下载,下载后直接解压即可,解压后便可单机exe文件打开 Ps:直接打开exe是会报错找不到json文件的,所以还要安装依赖环境 运行cypress项目前,必须vue-c ...