• AbstractApplicationContext#finishBeanFactoryInitialization总体流程分析


    当使用者通过调用BeanFactory#getBean(java.lang.String)会获取到Bean实例;

    那么Bean实例是在容器哪个时机创建的?

    这里以AnnotationConfigApplicationContext解析配置类(@Configuration)作为分析BeanDefinition加载为例

    AbstractApplicationContext#refresh中会调用AbstractApplicationContext#invokeBeanFactoryPostProcessors

    在前面分析了在AbstractApplicationContext#invokeBeanFactoryPostProcessors方法执行期间会创建BeanDefinitionRegistryPostProcessorBeanFactoryPostProcessor两个后置处理器,并将所有的beanDefinition加载到IOC容器;

    其中BeanDefinitionRegistryPostProcessor它的执行时机为所有的bean定义信息(BeanDefinition)将要被加载到容器的时候,BeanFactoryPostProcesso它的执行时机是在所有的bean定义信息已经加载到容器的时候;

    当beanDefinition被容器加载完后,AbstractApplicationContext#refresh会调用AbstractApplicationContext#finishBeanFactoryInitialization方法用于将剩余的非懒加载单例Bean实例化

    AbstractApplicationContext#finishBeanFactoryInitialization这方法里面有一个beanFactory.preInstantiateSingletons()方法的调用,用于初始化所有的非懒加载的单例Bean;

    DefaultListableBeanFactory#preInstantiateSingletons

    首先会先获取容器中所有beanDefinitionbeanName,需要根据beanName实例化Bean;

    根据beanDefinition判断是不是抽象的,且不是单例的,且不是懒加载的,在beanDefinition符合条件之后再判断beanName是否为FactoryBean类型,根据不同的条件,调用AbstractBeanFactory#getBean(java.lang.String)的入参也不同,如果beanName是FactoryBean类型的,调用AbstractBeanFactory#getBean(java.lang.String)的入参为:前缀&符号 + beanName;而beanName不是FactoryBean类型的,则将直接传入;

    AbstractBeanFactory#getBean该方法是一个空壳方法,没有任何的实现逻辑 真正的逻辑调用在doGetBean()中,该接口是实现了BeanFactory的getBean(String name)接口,这里调用链过于复杂,单独分析;

    最后所有实现了SmartInitializingSingleton接口的Bean会回调SmartInitializingSingleton#afterSingletonsInstantiated方法;

    从上面的流程也可以看出,它的触发时机是在BeanFactory引导期间的单例Bean实例化例结束时触发的回调接口; 

    SmartInitializingSingleton

    从某种程度来说, SmartInitializingSingleton接口可以是可以替代InitializatingBean的,但是两者的触发时机不同;InitializatingBean先于SmartInitializingSingleton执行;

    AbstractApplicationContext#finishBeanFactoryInitialization总体的大致流程图如下:

     

  • 相关阅读:
    07.Linux-CentOS系统库文件libaudit.so.1丢失问题
    06.Linux-RedHat系统网卡服务连不上活跃连接路径变化
    05.Linux-CentOS系统普通用户SSH远程问题
    04.Linux-CentOS系统SSH连接问题
    03.Linux-CentOS系统user用户改密码问题
    解决pycharm问题:module 'pip' has no attribute 'main'
    Centos7搭建主从DNS服务器
    docker 启动镜像报 WARNING: IPv4 forwarding is disabled. Networking will not work.
    dockerfile文件命令详解
    Elasticsearch集群搭建笔记(elasticsearch-6.3.0)
  • 原文地址:https://www.cnblogs.com/coder-zyc/p/15302877.html
Copyright © 2020-2023  润新知