• beanfactory中单例bean的初始化过程(一)


    Date 10.06 pm

    Point

    完成beanfactory中单例bean的初始化

    beanFactory.preInstantiateSingletons()

    1. 拿到所有的bean定义信息(在 beanDefinitionNames中,遍历list

    2. 获取到bean的定义信息

    3. 如果这个bean不是抽象,是单例,不是懒加载的

    4. 判断这个bean是否factorybean(判断这个bean有没有实现factoryBean接口),是的话,用工厂里面的方法去创建bean。

      • 调用getbean(&beanname) 获取到beanFactory对象。
    5. 调用getBean(beanName)创建bean

      • 调用 doGetBean()

      • transformedBeanName进入这个方法将之前工厂bean的前缀去除,将别名转成正式的名称

      • getSingleton检测单例缓存中是否有已构建的单实例bean,有就直接返回这个单例bean

        /** Cache of singleton objects: bean name to bean instance. */
        

      private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);
      ```
      所有实例过的单例bean都会在这注册,检查的时候还会判断当前bean有没有在创建过程中。如果有的话,会在earlySingletonObjects去获取,要是这个还是没有获取到的话,会去singletonFactories这个map中去获取,要是获取到的话就删除singletonFactories中的bean,转而在earlySingletonObjects这个map里面去注册

      • 没有获取到bean(开始创建bean的流程)
        • 就先判断下我们是不是正在创建这个bean的实例,避免循环引用的问题。
        • 获取bean的父工厂(这个主要是如果有Springmvc的话 可能会有这种父子工厂)这个父工厂要是能获取到的话,又会去调用父工厂的dogetbean方法,获取不到父工厂的话直接下一步
        • 标记当前bean已经创建,大概就是把当前beanname放到Collections.newSetFromMap(new ConcurrentHashMap<>(256))里面,防止多线程的时候多次创建单例bean
        • 获取bean的定义信息
        • 获取bean所依赖的其他bean,如果有,还是调用getbean的方式去构建那些依赖的bean
        • 如果这个bean是单例bean,回掉createBean,开始单例bean创建
          • 拿到bean的定义信息
          • 解析bean的定义的类型,检查这个定义信息中的beanClass是不是为空
          • 检测是否有bean方法被重写,有的话准备重写这个bean方法(也是检查bean定义信息里面的methodOverrides这个属性有没有值)
          • 让BeanPostProcessor提前拦截,返回代理对象resolveBeforeInstantiation()
            • 先根据定义信息中的beforeInstantiationResolved判断初始化之前有没有处理,有的话就不进入这个processor中了,
            • 然后判断这个值是不是由application定义的 和 判断当前factory中已经有了InstantiationAwareBeanPostProcessor这个processor了,然后去获取这个bean的目标class,然后调用InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation启动前置处理器,然后如果返回的bean有值的话,再调用applyBeanPostProcessorsAfterInitialization后置处理器,然后将bean定义信息中beforeInstantiationResolved这个参数赋值成这个返回的bean,然后返回这个bean

    https://github.com/fulln

  • 相关阅读:
    solaris 10 root忘记密码的解决方法
    c程序设计--指针与数组
    photoshop之色阶的使用
    Handling Errors Exceptionally Well in C++ 在C++中良好地捕获意外的错误
    自动换行 wordbreak:breakall和wordwrap:breakword
    透明度
    position:fixed在IE6下的实现
    JavaScript教程:常用DOM操作方法,JavaScriptDOM基本操作
    30 个免费的 UI 工具箱
    去掉虚线框兼容所有浏览器
  • 原文地址:https://www.cnblogs.com/wzqshb/p/11774767.html
Copyright © 2020-2023  润新知