容器初始化及SpringBean加载过程

对于Spring项目,应用上下文又常叫做Spring容器。

1. 创建Spring容器

Spring容器类型:AnnotationConfigServletWebServerApplicationContext。

容器中会生成一个DefaultListableBeanFactory类型的对象(下文简称beanFactory)。

DefaultListableBeanFactory继承了DefaultSingletonBeanRegistry。DefaultSingletonBeanRegistry就是Spring Bean管理的关键。

DefaultSingletonBeanRegistry继承了SimpleAliasRegistry并实现SingletonBeanRegistry,使得它既有别名注册的功能,又有单例bean注册的功能。它是一个通用的存储共享bean实例的地方。
在这里插入图片描述

  • AliasRegistry:提供别名注册的接口。
  • SimpleAliasRegistry:它简单地实现了AliasRegistry接口。
  • SingletonBeanRegistry:提供单例bean注册的接口。

创建Spring容器这个过程目前还未创建任何Spring管理的Bean实例。

2. 获取异常报告器

注册的SpringBean:

  • autoConfigurationReport -> ConditionEvaluationReport(条件评估报告)。

    记录自动化配置过程中条件匹配的详细信息及日志信息。
    在这里插入图片描述

3. 准备Spring容器

注册的SpringBean:

  • springApplicationArguments -> DefaultApplicationArguments
  • org.springframework.boot.context.ContextIdApplicationContextInitializer$ContextId -> ContextIdApplicationContextInitializer$ContextId
  • springBootLoggingSystem -> LogbackLoggingSystem
  • springBootBanner -> SpringApplicationBannerPrinter$PrintedBanner
  • springBootLogFile -> LogFile
  • springBootLoggerGroups -> LoggerGroups
    在这里插入图片描述

4. 刷新Spring容器

  1. 准备刷新

    prepareRefresh()

    刷新上下文环境,初始化上下文环境,对系统的环境便利或者系统属性进行准备和校验

  2. beanFactory刷新

    obtainFreshBeanFactory()

    销毁原有beanFactory,获取新的beanFactory,为每个bean生成BeanDefinition等。

  3. 准备bean工厂

    prepareBeanFactory(beanFactory)

    对bean工厂的工作功能进行填充,如:@Autowired、设置spel表、设置编辑注册器、添加applicationContextAwaerprocessor处理器等

    注册的SpringBean:

    • systemEnvironment -> Collections$UnmodifiableMap
    • environment -> StandardServletEnvironment
    • systemProperties -> Properties
  4. 后置处理bean工厂

    postProcessBeanFactory(beanFactory)

    允许在上下文子类中对 bean 工厂进行后置处理。

    在beanfactory加载完成所有的bean后,想修改其中某个bean的定义,或者对beanFactory做一些其他的配置,就可以在子类中对beanFactory进行后置处理(子类通过实现接口BeanFactoryPostProcessor来自定义后置处理)。

    BeanFactoryPostProcessor是针对BeanFactory的扩展,主要用在bean实例化之前,读取bean的定义,并可以修改它。

    后置处理器执行的时间是:在所有的beanDenifition加载完成之后,bean实例化之前执行。

  5. 调用bean工厂后置处理器

    invokeBeanFactoryPostProcessors(beanFactory)

    调用所有注册的、原始的bean工厂后置处理器。会实例化和调用所有 BeanFactoryPostProcessor(包括其子类 BeanDefinitionRegistryPostProcessor)。

    • 先处理用户手动注册的BeanFactoryPostProcessor,分为BeanDefinitionRegistryPostProcessor和BeanFactoryPostProcessor,并且BeanDefinitionRegistryPostProcessor会先调用其postXX方法
    • 从容器获取所有的BeanDefinitionRegistryPostProcessor类型,先处理实现PriorityOrdered类型的
    • 再从容器获取所有的BeanDefinitionRegistryPostProcessor类型,处理实现Ordered类型的
    • 再从容器获取所有的BeanDefinitionRegistryPostProcessor类型,处理剩下的,这里有个递归,知道所有的BeanDefinitionRegistryPostProcessor都处理完
    • BeanDefinitionRegistryPostProcessor也是BeanFactoryPostProcessor,最后处理BeanDefinitionRegistryPostProcessor从BeanFactoryPostProcessor继承的方法
    • 最后处理一般的BeanFactoryPostProcessor的postXXX方法。


    需要注意:

    • BeanDefinitionRegistryPostProcessor有可能会动态新增新的BeanDefinitionRegistryPostProcessor,所有这里每次都从容器中重新获得所有的BeanDefinitionRegistryPostProcessor。

    • BeanDefinitionRegistryPostProcessor的回调方法,先于BeanFactoryPostProcessor的回调方法执行。

    注册的SpringBean:

    • 所有的bean工厂后置处理器。
      在这里插入图片描述

    这一步完成后,容器中已有完整的BeanDefinition集合(所有需要spring容器管理的bean的BeanDefinition都在这里)。

  6. 注册bean后置处理器

    registerBeanPostProcessors(beanFactory)

    实例化和注册beanFactory中扩展了BeanPostProcessor的bean。例如:

    1. AutowiredAnnotationBeanPostProcessor(处理被@Autowired注解修饰的bean并注入)
    2. RequiredAnnotationBeanPostProcessor(处理被@Required注解修饰的方法)
    3. CommonAnnotationBeanPostProcessor(处理@PreDestroy、@PostConstruct、@Resource等多个注解的作用)等。


    BeanPostProcessor是针对bean的扩展,主要用在bean实例化之后,执行初始化方法前后,允许开发者对 bean 实例进行修改。

    注册的SpringBean:

    1. 所有的bean后置处理器。
      在这里插入图片描述

    这一步完成后,后续的生成的Spring bean已经支持自动装配(@Autowired、@Resource)等。

  7. 初始化消息源

    initMessageSource()

    初始化国际化工具类MessageSource。

    注册的SpringBean:

    1. 消息源MessageSource。在这里插入图片描述
  8. 初始化应用事件广播器

    initApplicationEventMulticaster()

    初始化应用事件广播器。

    注册的SpringBean:

    1. 应用事件广播器ApplicationEventMulticaster。
      在这里插入图片描述
  9. 初始化特殊的bean

    onRefresh()

    启动内置Web容器(如Tomcat),并初始化一些特殊的bean(如DataSource)。

    这阶段主要完成的事情:

    1. 初始化主题功能
    2. 启动SpringBoot的嵌入式Tomcat服务器
      1. 启动web容器
      2. 创建ServletContext
      3. 创建Listener
      4. 创建Filter
      5. 创建Servlet
    3. 初始化一些特殊的bean

    注册的SpringBean:

    1. web容器相关(如:ServletContext、Listener、Filter、Servlet等)
    2. 一些特殊的bean(如DataSource)
  10. 注册监听器

    registerListeners()

    注册监听器,并且广播earlyApplicationEvents(早期应用事件)。

  11. 完成bean工厂初始化

    finishBeanFactoryInitialization(beanFactory)

    该方法会初始化所有剩余的非懒加载单例bean,并调用BeanPostProcessors。

    除了一些内部的 bean、实现了BeanFactoryPostProcessor 接口的 bean、实现了BeanPostProcessor 接口的 bean,其他的非懒加载单例bean都会在这个方法中被初始化,BeanPostProcessor的触发也是在这个方法中。

  12. 完成刷新

    finishRefresh()

    通知生命周期处理器LifecycleProcessor完成刷新过程,同时发出ContextRefreshEvent通知容器刷新完成。

    该阶段完成的事情:

    1. 清除上下文资源缓存(如扫描中的ASM元数据)
    2. 初始化上下文的生命周期处理器,并刷新(找出Spring容器中实现了Lifecycle接口的bean并执行start()方法)
    3. 发布ContextRefreshedEvent事件告知对应的ApplicationListener进行响应的操作

至此,容器初始化及SpringBean创建完成。

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐