spring-framework 5.1 初始化非懒加载的单例bean流程

JAVA学习网 2020-10-18 06:00:50

AbstractApplicationContext#finishBeanFactoryInitialization

beanFactory.preInstantiateSingletons()

-> AbstractBeanFactory#getBean 开始获取Bean流程:

  1. DefaultSingletonBeanRegistry#getSingleton 从缓存中获取Bean实例
    1. 从3级缓存(singletonObjects)中获取。存在直接返回
    2. 不存在,从二级缓存(earlySingletonObjects)中获取, 存在直接返回
    3. 不存在,从一级缓存(singletonFactories)中获取, 存在则生产Bean,此时如果是代理对象,则生成对应的代理对象。保存到二级缓存中
  2. DefaultSingletonBeanRegistry#getSingleton 这个方法的入参就是beanName和factory的lambda表达式。
    1. DefaultSingletonBeanRegistry#getSingleton获取最终的Bean方法,从3级缓存(singletonObjects)拿,拿不到开始创建。
      1. singletonObject = singletonFactory.getObject(); 执行传入的singletonFactory方法 createBean(beanName, mbd, args); createBean方法也是封装了下面的方法Object beanInstance = doCreateBean(beanName, mbdToUse, args);
        1. AbstractAutowireCapableBeanFactory#createBeanInstance 新建简单bean(此时未设置属性)此时放入1级缓存 放的是factory对象(需要的话生产代理对象,也可以是普通Bean对象)addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
        2. AbstractAutowireCapableBeanFactory#populateBean 属性填充:
          1. AbstractBeanFactory#getBeanPostProcessors 获取bean所有后置处理器,遍历调用postProcessProperties方法。其中AutowiredAnnotationBeanPostProcessor#postProcessProperties 这个后置处理器进行依赖注入
            1. InjectionMetadata#inject 拿到所有的属性,遍历
              1. AutowiredFieldElement#inject 注入单个属性
                1. DefaultListableBeanFactory#resolveDependency 准备处理依赖,按不同类型调用不同的方法。其实走的是else流程,if里都是特殊的类型。
                  1. DefaultListableBeanFactory#doResolveDependency 拿到需要被注入的Bean的Candidates,这里的autowired首先按类型查询,当存在多个同类型的Candidate时,按名称查询。
                    1. DependencyDescriptor#resolveCandidate 处理拿到的这个candidate,获取Bean
                      1. AbstractBeanFactory#getBean-> AbstractAutowireCapableBeanFactory#doCreateBean 从头开始相同操作。
        3. 此时执行Bean的后置处理器
        4. AbstractBeanFactory#registerDisposableBeanIfNecessary ???好像是设置可销毁的Bean
      2. DefaultSingletonBeanRegistry#addSingleton 新创建的Bean需要将Bean放入一级缓存,并移除二级缓存和三级缓存。
    2. AbstractAutowireCapableBeanFactory#getObjectForBeanInstance 如果刚刚创建的是FactoryBean实例,则从Bean工厂中生产Bean实例对象。普通的Bean对象不做处理。还是刚刚获取or创建的Bean。

-> 加载完所有的Bean之后 执行Bean初始化回调

  • 如果Bean实现了SmartInitializingSingleton接口,执行它的实现方法afterSingletonsInstantiated
阅读(2412) 评论(0)