概述

  • 通过整理SpringBoot全流程,可以更好的俯视项目的运行流程,并且可以快速的定位到具体的代码,方便高效
  • 通过整理SpringBoot扩展点流程,可以更好的俯视Spring中bean的整个生命周期以及扩展的切入点,并且可以快速的定位到具体的代码,方便高效

SpringBoot全流程解析

  • 创建一个新的SpringApplication实例

    SpringApplication#SpringApplication(ResourceLoader, Class<?>...)

    • 从META-INF/spring.factories文件中加载内容

      SpringFactoriesLoader#loadSpringFactories

    • 设置初始化器

      SpringApplication#setInitializers

    • 设置监听器

      SpringApplication#setListeners

  • 调用run方法

    SpringApplication#run(java.lang.String...)

    • 开始监听器

      SpringApplicationRunListeners#starting

    • 打印logo

      SpringApplication#printBanner

    • 创建ApplicationContext

      SpringApplication#createApplicationContext

    • 准备上下文

      SpringApplication#prepareContext

      • 执行初始化器

        SpringApplication#applyInitializers

        总共有7个初始化器,遍历执行对应的initialize方法,以下两个比较重要

        • DelegatingApplicationContextInitializer

          调用 ApplicationContextInitializer#initialize方法

        • SharedMetadataReaderFactoryContextInitializer

          添加 CachingMetadataReaderFactoryPostProcessor后置处理器,用于注册 CachingMetadataReaderFactory和配置 ConfigurationClassPostProcessor

      • 加载beanDefinition到ApplicationContext中

        SpringApplication#load

        可以根据不同的source加载bean

        • 例如根据类加载beanDefinition(即Springboot默认的加载方式,传入主启动类)

          AnnotatedBeanDefinitionReader#doRegisterBean

          • 根据@ConditionalOnXXX注解决定是否跳过该beanDefinition的加载

            ConditionEvaluator#shouldSkip(AnnotatedTypeMetadata)

          • 解析该bean是否标注有@Primary、@Lazy注解

          • 然后创建并注册解析好的beanDefinition

      • 触发contextLoaded事件

        SpringApplicationRunListeners#contextLoaded

        • 回调ApplicationContextAware接口

          ApplicationContextAware#setApplicationContext

    • 刷新上下文

      SpringApplication#refreshContext

      • 调用子类的refresh方法

        ServletWebServerApplicationContext#refresh

        • 准备BeanFactory,添加后置处理器

          AbstractApplicationContext#prepareBeanFactory

          • 添加ApplicationContextAwareProcessor处理器
        • 处理BeanFactory

          AbstractApplicationContext#postProcessBeanFactory

          • 添加WebApplicationContextServletContextAwareProcessor处理器
        • 回调BeanFactoryPostProcessors

          AbstractApplicationContext#invokeBeanFactoryPostProcessors

          • 先回调BeanDefinitionRegistryPostProcessors接口

            • CachingMetadataReaderFactoryPostProcessor#postProcessBeanDefinitionRegistry

              做了以下两件事

              • 注册SharedMetadataReaderFactoryBean的beanDefinition
              • 配置ConfigurationClassPostProcessor
            • ConfigurationWarningsPostProcessor#postProcessBeanDefinitionRegistry

              没啥用

          • 再回调实现了PriorityOrdered接口的BeanDefinitionRegistryPostProcessors接口

            • ConfigurationClassPostProcessor#postProcessBeanDefinitionRegistry

              循环递归解析@Configuration配置类进一步加载所有的beanDefinition

              • 解析配置类

                ConfigurationClassParser#parse(Set)

                • 如果是注解配置类,则调用该方法循环递归解析

                  ConfigurationClassParser#doProcessConfigurationClass

                  • 如果被@Component注解标注,则先递归处理任何(嵌套)成员类

                  • 处理标注的@PropertySource注解

                  • 处理@ComponentScan注解,并将指定的路径下的所有类解析成beanDefinition

                    如果有遇到了配置类,则递归处理

                  • 处理@Import注解

                  • 处理@ImportResource注解

                  • 处理@Bean注解

          • 再回调实现了Ordered接口的BeanDefinitionRegistryPostProcessors接口

            没有对应的BeanDefinitionRegistryPostProcessors

          • 再回调剩下的BeanDefinitionRegistryPostProcessors接口

            一般回调自定义的BeanDefinitionRegistryPostProcessors

          • 在回调所有BeanDefinitionRegistryPostProcessors接口的父接口方法

            • CachingMetadataReaderFactoryPostProcessor#postProcessBeanFactory

              空方法

            • ConfigurationWarningsPostProcessor#postProcessBeanFactory

              空方法

            • ConfigurationClassPostProcessor#postProcessBeanFactory

              将需要增强的类(例如切面类等)通过cglib做增强,然后返回beanDefinition,以便后续实例化

              • 遍历需要增强的类,执行enhance方法进行cglib增强

                ConfigurationClassEnhancer#enhance

              • 添加ImportAwareBeanPostProcessor后置处理器

            • 自定义的BeanDefinitionRegistryPostProcessors的postProcessBeanFactory方法

          • =======================

          • 再回调实现了PriorityOrdered接口的BeanFactoryPostProcessors接口

            • PropertySourcesPlaceholderConfigurer#postProcessBeanFactory

              通过配置文件替换掉代码中对应 ${...}的占位符(即将配置参数赋值成员变量)

          • 再回调实现了Ordered接口的BeanFactoryPostProcessors接口

            没有BeanFactoryPostProcessors

          • 再回调剩下的BeanFactoryPostProcessors接口

            • EventListenerMethodProcessor#postProcessBeanFactory

              没啥用

            • PreserveErrorControllerTargetClassPostProcessor#postProcessBeanFactory

              没啥用

        • 注册BeanPostProcessors

          AbstractApplicationContext#registerBeanPostProcessors

          • 按照实现了PriorityOrdered接口、Ordered接口和普通的BeanPostProcessors进行排序并注册 注册如下,一共10个后置处理器(会因项目不同而不同)
            • ApplicationContextAwareProcessor
            • WebApplicationContextServletContextAwareProcessor
            • ImportAwareBeanPostProcessor
            • BeanPostProcessorChecker
            • ConfigurationPropertiesBindingPostProcessor
            • WebServerFactoryCustomizerBeanPostProcessor
            • ErrorPageRegistrarBeanPostProcessor
            • CommonAnnotationBeanPostProcessor
            • AutowiredAnnotationBeanPostProcessor
            • ApplicationListenerDetector
        • 刷新

          AbstractApplicationContext#onRefresh

          • 创建WebServer

            ServletWebServerApplicationContext#createWebServer

            • 创建ServletWebServerFactory

              ServletWebServerApplicationContext#getWebServerFactory

            • 创建并启动WebServer(例如tomcat)

              ServletWebServerFactory#getWebServer

        • 完成BeanFactory的实例化

          AbstractApplicationContext#finishBeanFactoryInitialization

          • 创建剩下的所有单实例bean

            DefaultListableBeanFactory#preInstantiateSingletons

            遍历所有beanNames,根据他们的beanDefinition进行实例化和初始化,在此期间并调用上面注册的

            BeanPostProcessors后置处理器对他们进行处理

            • 根据beanName获取对应的单实例bean,如果没有,则进行创建

              AbstractBeanFactory#getBean(String)

              • 尝试从ioc容器中获取bean

                DefaultSingletonBeanRegistry#getSingleton(String)

              • 如果没获取到,则标记bean正在创建,然后接下来开始创建bean

                AbstractBeanFactory#markBeanAsCreated

              • 先创建好bean的依赖

                DefaultSingletonBeanRegistry#registerDependentBean

              • 再通过getSingleton的重载方法进行创建bean

                DefaultSingletonBeanRegistry#getSingleton(String, ObjectFactory<?>)

                • 接下来就是Spring的核心内容,在下面的Spring扩展点流程中有了,这里就不赘述了
              • 创建成功后,返回创建的bean实例

    • 调用ApplicationRunner接口(先)和CommandLineRunner接口(后)

      SpringApplication#callRunners

SpringBoot扩展点流程解析

主流程图

SpringBoot扩展主流程图-2020-11-05-02:11:33.jpg

主流程及具体代码位置:引用时请注明出处:http://luyingjie.cn

ApplicationContextInitializer#initialize

需要特殊指定才可以使用

调用点:DelegatingApplicationContextInitializer#applyInitializers

要使用ApplicationContextInitializer进行初始化,有三种方式:

  1. 在配置文件中指定:context.initializer.classes=com.example.demo.test.ApplicationContextInitializerTest

  2. 在项目的类路径下添加META-INF/spring.factories指定内容:org.springframework.context.ApplicationContextInitializer=com.example.demo.test.ApplicationContextInitializerTest

  3. 通过代码添加ApplicationContextInitializer:

    public static void main(String[] args) {
      SpringApplication application = new SpringApplication(DemoApplication.class);
      application.addInitializers(new ApplicationContextInitializerTest());
      application.run(args);
    }
    

BeanDefinitionRegistryPostProcessor#postProcessBeanDefinitionRegistry

调用点:AbstractApplicationContext#invokeBeanFactoryPostProcessors

调用顺序:实现PriorityOrdered接口>实现Ordered接口>未实现接口的后置处理器

SpringBoot会按照顺序依次调用:

CachingMetadataReaderFactoryPostProcessor#postProcessBeanDefinitionRegistry

ConfigurationWarningsPostProcessor#postProcessBeanDefinitionRegistry

ConfigurationClassPostProcessor#postProcessBeanDefinitionRegistry

一般我们自己定义的BeanDefinitionRegistryPostProcessors后置处理器会在这里执行


  • CachingMetadataReaderFactoryPostProcessor#postProcessBeanDefinitionRegistry

    做了以下两件事:

    • 注册SharedMetadataReaderFactoryBean的beanDefinition
    • 配置ConfigurationClassPostProcessor
  • ConfigurationWarningsPostProcessor#postProcessBeanDefinitionRegistry

    没用

  • ConfigurationClassPostProcessor#postProcessBeanDefinitionRegistry

    循环递归解析@Configuration配置类进一步加载所有的beanDefinition

    • 解析配置类

      ConfigurationClassParser#parse(Set)

      • 如果是注解配置类,则调用该方法循环递归解析 ConfigurationClassParser#doProcessConfigurationClass
        • 如果被@Component注解标注,则先递归处理任何(嵌套)成员类
        • 处理标注的@PropertySource注解
        • 处理@ComponentScan注解,并将指定的路径下的所有类解析成beanDefinition 如果有遇到了配置类,则递归处理
        • 处理@Import注解
        • 处理@ImportResource注解
        • 处理@Bean注解

BeanDefinitionRegistryPostProcessor#postProcessBeanFactory

调用点:AbstractApplicationContext#invokeBeanFactoryPostProcessors

调用顺序:实现PriorityOrdered接口>实现Ordered接口>未实现接口的后置处理器

SpringBoot会按照顺序依次调用:

CachingMetadataReaderFactoryPostProcessor#postProcessBeanFactory

ConfigurationWarningsPostProcessor#postProcessBeanFactory

ConfigurationClassPostProcessor#postProcessBeanFactory

PropertySourceOrderingPostProcessor#postProcessBeanFactory


  • CachingMetadataReaderFactoryPostProcessor#postProcessBeanFactory

    空方法

  • ConfigurationWarningsPostProcessor#postProcessBeanFactory

    空方法

  • ConfigurationClassPostProcessor#postProcessBeanFactory

    将需要增强的类(例如切面类等)通过cglib做增强,然后返回beanDefinition,以便后续实例化

    • 遍历需要增强的类,执行enhance方法进行cglib增强 ConfigurationClassEnhancer#enhance
    • 添加ImportAwareBeanPostProcessor后置处理器

BeanFactoryPostProcessor#postProcessBeanFactory

调用点:AbstractApplicationContext#invokeBeanFactoryPostProcessors 调用顺序:实现PriorityOrdered接口>实现Ordered接口>未实现接口的后置处理器

SpringBoot会按照顺序依次调用:

PropertySourcesPlaceholderConfigurer#postProcessBeanFactory

EventListenerMethodProcessor#postProcessBeanFactory

PreserveErrorControllerTargetClassPostProcessor#postProcessBeanFactory


  • PropertySourcesPlaceholderConfigurer#postProcessBeanFactory

    通过配置文件替换掉代码中对应 ${...}的占位符(即将配置参数赋值成员变量)

  • EventListenerMethodProcessor#postProcessBeanFactory

    没啥用

  • PreserveErrorControllerTargetClassPostProcessor#postProcessBeanFactory

    没啥用

Aware

调用点:ApplicationContextAwareProcessor#invokeAwareInterfaces(是一个后置处理器,比较特殊,所以拎出来)

  • BeanNameAware#setBeanName
  • BeanFactoryAware#setBeanFactory
  • ResourceLoaderAware#setResourceLoader
  • EnvironmentAware#setEnvironment
  • ApplicationContextAware#setApplicationContext

实现了这些接口的类会被回调对应的方法

InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation

调用点:AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsBeforeInitialization

SpringBoot会按照顺序调用下面的后置处理器:

ImportAwareBeanPostProcessor#postProcessBeforeInstantiation

CommonAnnotationBeanPostProcessor#postProcessBeforeInstantiation

AutowiredAnnotationBeanPostProcessor#postProcessBeforeInstantiation

这些后置处理器的不是固定的,需要根据项目中导入的和自动配置的情况有所变动


  • ImportAwareBeanPostProcessor#postProcessBeforeInstantiation

    调用父类InstantiationAwareBeanPostProcessorAdapter#postProcessBeforeInstantiation方法

    返回null

  • CommonAnnotationBeanPostProcessor#postProcessBeforeInstantiation

    返回null

  • AutowiredAnnotationBeanPostProcessor#postProcessBeforeInstantiation

    调用父类InstantiationAwareBeanPostProcessorAdapter#postProcessBeforeInstantiation方法

    返回null

构造方法

调用点:AbstractAutowireCapableBeanFactory#instantiateBean

MergedBeanDefinitionPostProcessor#postProcessMergedBeanDefinition

调用点:AbstractAutowireCapableBeanFactory#applyMergedBeanDefinitionPostProcessors

SpringBoot会按照顺序调用下面的后置处理器:

CommonAnnotationBeanPostProcessor#postProcessMergedBeanDefinition

AutowiredAnnotationBeanPostProcessor#postProcessMergedBeanDefinition

ApplicationListenerDetector#postProcessMergedBeanDefinition


  • CommonAnnotationBeanPostProcessor#postProcessMergedBeanDefinition 没啥用
  • AutowiredAnnotationBeanPostProcessor#postProcessMergedBeanDefinition 没啥用
  • ApplicationListenerDetector#postProcessMergedBeanDefinition 没啥用

InstantiationAwareBeanPostProcessor#postProcessAfterInstantiation

调用点:AbstractAutowireCapableBeanFactory#populateBean

SpringBoot会按照顺序调用下面的后置处理器:

ImportAwareBeanPostProcessor#postProcessAfterInstantiation

CommonAnnotationBeanPostProcessor#postProcessAfterInstantiation

AutowiredAnnotationBeanPostProcessor#postProcessAfterInstantiation


  • ImportAwareBeanPostProcessor#postProcessAfterInstantiation

    调用父类InstantiationAwareBeanPostProcessorAdapter#postProcessAfterInstantiation方法

    返回true

  • CommonAnnotationBeanPostProcessor#postProcessAfterInstantiation

    返回true

  • AutowiredAnnotationBeanPostProcessor#postProcessAfterInstantiation

    调用父类InstantiationAwareBeanPostProcessorAdapter#postProcessAfterInstantiation方法

    返回true

InstantiationAwareBeanPostProcessor#postProcessProperties

调用点:AbstractAutowireCapableBeanFactory#populateBean

SpringBoot会按照顺序调用下面的后置处理器:

ImportAwareBeanPostProcessor#postProcessProperties

CommonAnnotationBeanPostProcessor#postProcessProperties

AutowiredAnnotationBeanPostProcessor#postProcessProperties


  • ImportAwareBeanPostProcessor#postProcessProperties

    没啥用

  • CommonAnnotationBeanPostProcessor#postProcessProperties

    没啥用

  • AutowiredAnnotationBeanPostProcessor#postProcessProperties

    对bean进行属性注入

属性注入

调用点:AutowiredAnnotationBeanPostProcessor#postProcessProperties

通过 AutowiredAnnotationBeanPostProcessor后置处理器进行属性注入,例如调用setter方法设置属性

BeanPostProcessor#postProcessBeforeInitialization

调用点:AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsBeforeInitialization

SpringBoot会按照顺序调用下面的后置处理器:

ApplicationContextAwareProcessor#postProcessBeforeInitialization

WebApplicationContextServletContextAwareProcessor#postProcessBeforeInitialization

ImportAwareBeanPostProcessor#postProcessBeforeInitialization

BeanPostProcessorChecker#postProcessBeforeInitialization

ConfigurationPropertiesBindingPostProcessor#postProcessBeforeInitialization

WebServerFactoryCustomizerBeanPostProcessor#postProcessBeforeInitialization

ErrorPageRegistrarBeanPostProcessor#postProcessBeforeInitialization

CommonAnnotationBeanPostProcessor#postProcessBeforeInitialization

AutowiredAnnotationBeanPostProcessor#postProcessBeforeInitialization

ApplicationListenerDetector#postProcessBeforeInitialization

这些后置处理器的不是固定的,需要根据项目中导入的和自动配置的情况有所变动


  • ApplicationContextAwareProcessor#postProcessBeforeInitialization

    对EnvironmentAware、ApplicationContextAware等接口进行回调

    返回bean

  • WebApplicationContextServletContextAwareProcessor#postProcessBeforeInitialization

    调用父类ServletContextAwareProcessor#postProcessBeforeInitialization方法,对实现了ServletContextAware接口的bean回调setServletConfig方法

    返回bean

  • ImportAwareBeanPostProcessor#postProcessBeforeInitialization

    • 调用实现了ImportAware接口的setImportMetadata方法
    • 返回bean
  • BeanPostProcessorChecker#postProcessBeforeInitialization

    返回bean

  • ConfigurationPropertiesBindingPostProcessor#postProcessBeforeInitialization

    绑定@ConfigurationProperties注解相关的配置参数

    返回bean

  • WebServerFactoryCustomizerBeanPostProcessor#postProcessBeforeInitialization

    返回bean

  • ErrorPageRegistrarBeanPostProcessor#postProcessBeforeInitialization

    返回bean

  • CommonAnnotationBeanPostProcessor#postProcessBeforeInitialization

    调用父类InitDestroyAnnotationBeanPostProcessor#postProcessBeforeInitialization方法

    调用了标注了 @PostConstruct注解的方法

    返回bean

  • AutowiredAnnotationBeanPostProcessor#postProcessBeforeInitialization

    调用父类InstantiationAwareBeanPostProcessorAdapter#postProcessBeforeInitialization方法

    返回bean

  • ApplicationListenerDetector#postProcessBeforeInitialization

    返回bean

@PostConstruct

通过 CommonAnnotationBeanPostProcessor后置处理器完成的调用

调用点:CommonAnnotationBeanPostProcessor#postProcessBeforeInitialization

CommonAnnotationBeanPostProcessor没有覆盖父类InitDestroyAnnotationBeanPostProcessor的postProcessBeforeInitialization方法,因此调用的就是父类的方法

调用标注有@PostConstruct注解的方法

InitializingBean#afterPropertiesSet

调用点:AbstractAutowireCapableBeanFactory#initializeBean

调用实现了InitializingBean接口的bean的afterPropertiesSet方法

BeanPostProcessor#postProcessAfterInitialization

调用点:AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsAfterInitialization

SpringBoot会按照顺序调用下面的后置处理器:

ApplicationContextAwareProcessor#postProcessAfterInitialization

WebApplicationContextServletContextAwareProcessor#postProcessAfterInitialization

ImportAwareBeanPostProcessor#postProcessAfterInitialization

BeanPostProcessorChecker#postProcessAfterInitialization

ConfigurationPropertiesBindingPostProcessor#postProcessAfterInitialization

WebServerFactoryCustomizerBeanPostProcessor#postProcessAfterInitialization

ErrorPageRegistrarBeanPostProcessor#postProcessAfterInitialization

CommonAnnotationBeanPostProcessor#postProcessAfterInitialization

AutowiredAnnotationBeanPostProcessor#postProcessAfterInitialization

ApplicationListenerDetector#postProcessAfterInitialization

这些后置处理器的不是固定的,需要根据项目中导入的和自动配置的情况有所变动


  • ApplicationContextAwareProcessor#postProcessAfterInitialization

    调用BeanPostProcessor接口的默认方法

    返回bean

  • WebApplicationContextServletContextAwareProcessor#postProcessAfterInitialization

    调用父类ServletContextAwareProcessor#postProcessAfterInitialization方法

    返回bean

  • ImportAwareBeanPostProcessor#postProcessAfterInitialization

    调用父类InstantiationAwareBeanPostProcessorAdapter#postProcessAfterInitialization方法

    返回bean

  • BeanPostProcessorChecker#postProcessAfterInitialization

    返回bean

  • ConfigurationPropertiesBindingPostProcessor#postProcessAfterInitialization

    调用BeanPostProcessor接口的默认方法

    返回bean

  • WebServerFactoryCustomizerBeanPostProcessor#postProcessAfterInitialization

    返回bean

  • ErrorPageRegistrarBeanPostProcessor#postProcessAfterInitialization

    返回bean

  • CommonAnnotationBeanPostProcessor#postProcessAfterInitialization

    调用父类InitDestroyAnnotationBeanPostProcessor#postProcessAfterInitialization方法

    返回bean

  • AutowiredAnnotationBeanPostProcessor#postProcessAfterInitialization

    调用父类InstantiationAwareBeanPostProcessorAdapter#postProcessAfterInitialization方法

    返回bean

  • ApplicationListenerDetector#postProcessAfterInitialization

    返回bean

ApplicationRunner#run

等SpringBoot全部启动完之后执行

调用点:SpringApplication#callRunners

CommandLineRunner#run

等SpringBoot全部启动完之后执行

调用点:SpringApplication#callRunners

@PreDestroy

通过 CommonAnnotationBeanPostProcessor后置处理器完成的调用

调用点:DisposableBeanAdapter#destroy

0条评论
头像
ICP证 : 浙ICP备18021271号