关于Spring 与 Spring Boot 的一些图

Spring Framework 启动流程

1. 流程图

以下流程图展示了 Spring Framework 从创建 ApplicationContext 到完成初始化的关键步骤。

flowchart TD
    A[启动入口: main 方法] --> B[创建 AnnotationConfigApplicationContext]
    B --> C[注册配置类]
    C --> D["调用 refresh() 方法"]
    D --> E["prepareRefresh()"]
    E --> F["obtainFreshBeanFactory()"]
    F --> G["refreshBeanFactory()"]
    G --> H[加载 Bean 定义]
    H --> I["prepareBeanFactory()"]
    I --> J[配置 BeanFactory]
    J --> K["invokeBeanFactoryPostProcessors()"]
    K --> L[注册 BeanPostProcessors]
    L --> M["initializeMessageSource()"]
    M --> N["finishBeanFactoryInitialization()"]
    N --> O["preInstantiateSingletons()"]
    O --> P["finishRefresh()"]
    P --> Q[应用准备就绪]

图示解释:

  1. 启动入口:通过 main 方法启动应用。
  2. 创建 ApplicationContext:实例化 AnnotationConfigApplicationContext
  3. 注册配置类:注册 Java 配置类(使用 @Configuration 注解)。
  4. 调用 refresh() 方法:初始化上下文。
  5. **prepareRefresh()**:执行准备工作,如设置环境等。
  6. **obtainFreshBeanFactory()**:获取 BeanFactory 并刷新。
  7. **refreshBeanFactory()**:创建新的 DefaultListableBeanFactory 并加载 Bean 定义。
  8. 加载 Bean 定义:读取并解析 Bean 配置。
  9. **prepareBeanFactory()**:配置 BeanFactory,如设置类加载器、忽略依赖等。
  10. **invokeBeanFactoryPostProcessors()**:执行所有的 BeanFactoryPostProcessor
  11. 注册 BeanPostProcessors:注册所有的 BeanPostProcessor
  12. **initializeMessageSource()**:初始化消息源,支持国际化。
  13. **finishBeanFactoryInitialization()**:预实例化所有非懒加载的单例 Bean。
  14. **preInstantiateSingletons()**:遍历并实例化单例 Bean。
  15. **finishRefresh()**:完成刷新,发布 ContextRefreshedEvent
  16. 应用准备就绪:应用上下文初始化完成,应用已准备好使用。

2. 时序图

以下时序图展示了 Spring Framework 在启动过程中各个组件之间的交互。

sequenceDiagram
    participant App as Application
    participant Context as AnnotationConfigApplicationContext
    participant BeanFactory as DefaultListableBeanFactory
    participant PostProcessors as BeanFactoryPostProcessor
    participant BeanPostProcessors as BeanPostProcessor
    participant MessageSource as MessageSource

    App->>Context: new AnnotationConfigApplicationContext(AppConfig.class)
    Context->>Context: register(AppConfig.class)
    Context->>Context: refresh()
    Context->>BeanFactory: create BeanFactory
    BeanFactory->>BeanFactory: loadBeanDefinitions()
    Context->>Context: prepareBeanFactory()
    Context->>PostProcessors: invokeBeanFactoryPostProcessors()
    Context->>BeanPostProcessors: registerBeanPostProcessors()
    Context->>MessageSource: initializeMessageSource()
    Context->>BeanFactory: preInstantiateSingletons()
    Context->>App: publish ContextRefreshedEvent
    App->>Context: Application Ready

图示解释:

  1. 应用程序实例化 AnnotationConfigApplicationContext 并注册配置类
  2. 调用 refresh() 方法,此时创建 BeanFactory 并加载 Bean 定义。
  3. 准备 BeanFactory,配置类加载器和忽略特定接口。
  4. **执行所有的 BeanFactoryPostProcessor**,如 ConfigurationClassPostProcessor
  5. **注册所有的 BeanPostProcessor**,如 AutowiredAnnotationBeanPostProcessor
  6. **初始化 MessageSource**,支持国际化功能。
  7. 预实例化所有单例 Bean,确保 Bean 在应用启动前被创建。
  8. **完成刷新并发布 ContextRefreshedEvent**,应用准备就绪。

3. 类图

以下类图展示了 Spring Framework 启动过程中主要类之间的关系。

classDiagram
    class Application {
        +main(String[] args)
    }

    class AnnotationConfigApplicationContext {
        +register(Class... classes)
        +refresh()
        +getBean(String name)
        +close()
    }

    class DefaultListableBeanFactory {
        +loadBeanDefinitions()
        +preInstantiateSingletons()
    }

    class BeanFactoryPostProcessor {
        +postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory)
    }

    class BeanPostProcessor {
        +postProcessBeforeInitialization(Object bean, String beanName)
        +postProcessAfterInitialization(Object bean, String beanName)
    }

    class MessageSource {
        +getMessage(String code, Object[] args, Locale locale)
    }

    Application --> AnnotationConfigApplicationContext
    AnnotationConfigApplicationContext --> DefaultListableBeanFactory
    AnnotationConfigApplicationContext --> BeanFactoryPostProcessor
    AnnotationConfigApplicationContext --> BeanPostProcessor
    AnnotationConfigApplicationContext --> MessageSource

类图解释:

  • Application:应用程序的入口,包含 main 方法。
  • AnnotationConfigApplicationContext:Spring 的 ApplicationContext 实现,负责管理 Bean 的生命周期。
  • DefaultListableBeanFactory:默认的 BeanFactory 实现,负责加载和管理 Bean 定义。
  • BeanFactoryPostProcessor:用于在 BeanFactory 初始化后、Bean 实例化前处理 Bean 配置。
  • BeanPostProcessor:用于在 Bean 初始化前后进行额外处理。
  • MessageSource:用于资源文件的消息解析,支持国际化。

Spring Boot 启动流程

1. 流程图

以下流程图展示了 Spring Boot 从调用 SpringApplication.run 到应用准备就绪的关键步骤。

flowchart TD
    A["启动入口: main 方法] --> B[调用 SpringApplication.run()"]
    B --> C[创建 SpringApplication 实例]
    C --> D[准备环境]
    D --> E[应用初始izers]
    E --> F[创建 ApplicationContext]
    F --> G[应用 ApplicationContext Initializers]
    G --> H[加载 Bean 定义和自动配置]
    H --> I[刷新 ApplicationContext]
    I --> J[调用 BeanFactoryPostProcessors]
    J --> K[注册 BeanPostProcessors]
    K --> L[初始化 MessageSource]
    L --> M[预实例化单例 Beans]
    M --> N[执行 CommandLineRunner 和 ApplicationRunner]
    N --> O["启动嵌入式 Web 服务器 (如果是 Web 应用)"]
    O --> P[发布 ApplicationReadyEvent]
    P --> Q[应用准备就绪]

图示解释:

  1. 启动入口:通过 main 方法并调用 SpringApplication.run
  2. 创建 SpringApplication 实例:配置启动参数和环境。
  3. 准备环境:设置 EnvironmentPropertySources,加载配置文件。
  4. 应用 Initializers:运行所有的 ApplicationContextInitializer
  5. **创建 ApplicationContext**:根据应用类型(例如,Web 应用)创建合适的上下文。
  6. 加载 Bean 定义和自动配置:通过 @EnableAutoConfiguration 导入自动配置类。
  7. **刷新 ApplicationContext**:初始化上下文,加载 Bean,注册后处理器。
  8. **调用 BeanFactoryPostProcessors**:执行所有的 BeanFactoryPostProcessor
  9. **注册 BeanPostProcessors**:注册后处理器以处理 Bean 的生命周期。
  10. **初始化 MessageSource**:支持国际化。
  11. 预实例化单例 Beans:确保所有非懒加载的 Bean 被创建。
  12. **执行 CommandLineRunnerApplicationRunner**:在应用启动后执行特定逻辑。
  13. 启动嵌入式 Web 服务器:例如,Tomcat、Jetty 或 Undertow。
  14. **发布 ApplicationReadyEvent**:应用完全启动并准备就绪。

2. 时序图

以下时序图展示了 Spring Boot 在启动过程中各个组件之间的交互。

sequenceDiagram
    participant App as Application
    participant SpringApp as SpringApplication
    participant Listeners as SpringApplicationRunListeners
    participant Environment as ConfigurableEnvironment
    participant Initializers as ApplicationContextInitializer
    participant Context as ConfigurableApplicationContext
    participant BeanFactory as ConfigurableListableBeanFactory
    participant AutoConfig as AutoConfiguration
    participant WebServer as EmbeddedWebServer
    participant Runners as CommandLineRunner/ApplicationRunner

    App->>SpringApp: SpringApplication.run(MyApplication.class, args)
    SpringApp->>Listeners: Call runListeners.starting()
    SpringApp->>SpringApp: prepareEnvironment()
    SpringApp->>Environment: Configure Environment (property sources)
    SpringApp->>Listeners: Call runListeners.environmentPrepared()
    SpringApp->>Listeners: Call runListeners.contextPrepared()
    SpringApp->>Initializers: Apply ApplicationContextInitializers
    SpringApp->>SpringApp: createApplicationContext()
    SpringApp->>Context: Instantiate ApplicationContext
    Context->>SpringApp: Configure ApplicationContext
    SpringApp->>Listeners: Call runListeners.contextLoaded()
    SpringApp->>Context: Refresh ApplicationContext
    Context->>BeanFactory: Invoke BeanFactoryPostProcessors
    Context->>Context: Register BeanPostProcessors
    Context->>AutoConfig: Load AutoConfiguration classes
    Context->>Context: Refresh and Initialize Beans
    Context->>WebServer: Start Embedded Web Server
    Context->>Runners: Execute CommandLineRunner/ApplicationRunner
    SpringApp->>Listeners: Call runListeners.running()
    SpringApp->>Listeners: Call runListeners.ready()
    SpringApp-->App: Return ApplicationContext

图示解释:

  1. **应用程序调用 SpringApplication.run**。
  2. **SpringApplicationRunListeners**:监听应用启动的各个阶段(starting、environmentPrepared、contextPrepared、contextLoaded、running、ready)。
  3. 准备环境:配置 Environment,加载属性源,如 application.properties
  4. **应用 ApplicationContextInitializer**:对 ApplicationContext 进行初始化。
  5. **创建 ApplicationContext**:根据应用类型(Web 或非 Web)创建合适的上下文。
  6. **刷新 ApplicationContext**:加载 Bean 定义,注册后处理器,执行自动配置。
  7. 加载自动配置类:通过 @EnableAutoConfiguration 导入自动配置。
  8. 启动嵌入式 Web 服务器:如果是 Web 应用,启动服务器。
  9. **执行 CommandLineRunnerApplicationRunner**:在应用启动后执行特定任务。
  10. **发布 ApplicationReadyEvent**:应用完全启动并准备就绪。

3. 类图

以下类图展示了 Spring Boot 启动过程中主要类之间的关系。

classDiagram
    class Application {
        +main(String[] args)
    }

    class SpringApplication {
        +run(Class primarySource, String[] args)
        +prepareEnvironment()
        +createApplicationContext()
        +refresh(ApplicationContext)
        +callRunners(ApplicationContext, ApplicationArguments)
    }

    class ConfigurableEnvironment {
        +getProperty(String key)
        +setProperty(String key, String value)
    }

    class ApplicationContextInitializer {
        +initialize(ConfigurableApplicationContext context)
    }

    class ConfigurableApplicationContext {
        +refresh()
        +getBean(String name)
        +close()
    }

    class ConfigurableListableBeanFactory {
        +registerBeanDefinition()
        +getBean()
    }

    class AutoConfiguration {
        +@Configuration classes
    }

    class EmbeddedWebServer {
        +start()
        +stop()
    }

    class CommandLineRunner {
        +run(String... args)
    }

    class ApplicationRunner {
        +run(ApplicationArguments args)
    }

    Application --> SpringApplication
    SpringApplication --> ConfigurableEnvironment
    SpringApplication --> ApplicationContextInitializer
    SpringApplication --> ConfigurableApplicationContext
    ConfigurableApplicationContext --> ConfigurableListableBeanFactory
    SpringApplication --> AutoConfiguration
    SpringApplication --> EmbeddedWebServer
    SpringApplication --> CommandLineRunner
    SpringApplication --> ApplicationRunner

类图解释:

  • Application:应用程序的入口,包含 main 方法。
  • SpringApplication:核心类,负责启动 Spring Boot 应用。
  • ConfigurableEnvironment:环境配置类,管理属性源和环境变量。
  • ApplicationContextInitializer:用于在 ApplicationContext 刷新前初始化上下文。
  • ConfigurableApplicationContext:可配置的应用上下文,管理 Bean 的生命周期。
  • ConfigurableListableBeanFactory:可配置的 BeanFactory,管理 Bean 定义和实例化。
  • AutoConfiguration:自动配置类,基于类路径和环境自动配置 Bean。
  • EmbeddedWebServer:嵌入式 Web 服务器,如 Tomcat、Jetty。
  • CommandLineRunnerApplicationRunner:接口,用于在应用启动后执行特定逻辑。

对比图示

为更清晰地理解 Spring Framework 和 Spring Boot 的启动流程,以下是它们的启动流程对比图。

启动流程对比流程图

flowchart LR
    subgraph SpringFramework
        A1[main 方法] --> A2[创建 AnnotationConfigApplicationContext]
        A2 --> A3[注册配置类]
        A3 --> A4["调用 refresh()"]
        A4 --> A5["prepareRefresh()"]
        A5 --> A6["obtainFreshBeanFactory()"]
        A6 --> A7["refreshBeanFactory()"]
        A7 --> A8[加载 Bean 定义]
        A8 --> A9["prepareBeanFactory()"]
        A9 --> A10["invokeBeanFactoryPostProcessors()"]
        A10 --> A11[注册 BeanPostProcessors]
        A11 --> A12["initializeMessageSource()"]
        A12 --> A13["finishBeanFactoryInitialization()"]
        A13 --> A14["preInstantiateSingletons()"]
        A14 --> A15["finishRefresh()"]
        A15 --> A16[应用准备就绪]
    end

    subgraph SpringBoot
        B1["main 方法] --> B2[调用 SpringApplication.run()"]
        B2 --> B3[创建 SpringApplication 实例]
        B3 --> B4[准备环境]
        B4 --> B5[应用 Initializers]
        B5 --> B6[创建 ApplicationContext]
        B6 --> B7[应用 Initializers]
        B7 --> B8[加载 Bean 定义和自动配置]
        B8 --> B9[刷新 ApplicationContext]
        B9 --> B10[调用 BeanFactoryPostProcessors]
        B10 --> B11[注册 BeanPostProcessors]
        B11 --> B12["initializeMessageSource()"]
        B12 --> B13[预实例化单例 Beans]
        B13 --> B14[执行 CommandLineRunner 和 ApplicationRunner]
        B14 --> B15[启动嵌入式 Web 服务器]
        B15 --> B16[发布 ApplicationReadyEvent]
        B16 --> B17[应用准备就绪]
    end

图示解释:

  • Spring Framework:从 main 方法开始,手动创建并配置 ApplicationContext,逐步刷新上下文并完成初始化。
  • Spring Boot:从 main 方法调用 SpringApplication.run,自动配置环境、加载 Bean 定义和自动配置,刷新上下文,启动嵌入式服务器,并发布准备就绪事件。

启动流程对比时序图

以下时序图对比了 Spring Framework 和 Spring Boot 的启动过程中主要方法和组件的交互。

sequenceDiagram
    participant SF_App as SpringFramework Application
    participant SF_Context as AnnotationConfigApplicationContext
    participant SF_BF as DefaultListableBeanFactory
    participant SF_PostProc as BeanFactoryPostProcessor
    participant SF_BP as BeanPostProcessor
    participant SF_MS as MessageSource

    participant SB_App as SpringBoot Application
    participant SB_SpringApp as SpringApplication
    participant SB_Listeners as SpringApplicationRunListeners
    participant SB_Env as ConfigurableEnvironment
    participant SB_Init as ApplicationContextInitializer
    participant SB_Context as ConfigurableApplicationContext
    participant SB_AutoConfig as AutoConfiguration
    participant SB_Web as EmbeddedWebServer
    participant SB_Runners as CommandLineRunner/ApplicationRunner

    %% Spring Framework Sequence
    SF_App->>SF_Context: new AnnotationConfigApplicationContext(AppConfig.class)
    SF_Context->>SF_Context: register(AppConfig.class)
    SF_Context->>SF_Context: refresh()
    SF_Context->>SF_BF: create BeanFactory
    SF_BF->>SF_BF: loadBeanDefinitions()
    SF_Context->>SF_Context: prepareBeanFactory()
    SF_Context->>SF_PostProc: invokeBeanFactoryPostProcessors()
    SF_Context->>SF_BP: register BeanPostProcessors
    SF_Context->>SF_MS: initializeMessageSource()
    SF_Context->>SF_BF: preInstantiateSingletons()
    SF_Context->>SF_App: publish ContextRefreshedEvent
    SF_App->>SF_Context: Application Ready

    %% Spring Boot Sequence
    SB_App->>SB_SpringApp: SpringApplication.run(MyApplication.class, args)
    SB_SpringApp->>SB_Listeners: starting()
    SB_SpringApp->>SB_SpringApp: prepareEnvironment()
    SB_SpringApp->>SB_Env: Configure Environment
    SB_SpringApp->>SB_Listeners: environmentPrepared()
    SB_SpringApp->>SB_SpringApp: applyInitializers()
    SB_SpringApp->>SB_Context: createApplicationContext()
    SB_Context->>SB_SpringApp: Configure ApplicationContext
    SB_SpringApp->>SB_AutoConfig: Load AutoConfiguration
    SB_SpringApp->>SB_Context: refresh()
    SB_Context->>SB_SpringApp: invoke BeanFactoryPostProcessors()
    SB_Context->>SB_Context: register BeanPostProcessors
    SB_Context->>SB_AutoConfig: apply AutoConfiguration
    SB_Context->>SB_Web: start Embedded Web Server
    SB_Context->>SB_Runners: execute Runners
    SB_SpringApp->>SB_Listeners: running(), ready()
    SB_App->>SB_Context: Application Ready

图示解释:

  • Spring Framework

    • 应用程序手动创建 AnnotationConfigApplicationContext,注册配置类,刷新上下文。
    • BeanFactory 加载 Bean 定义,应用 BeanFactoryPostProcessor,注册 BeanPostProcessor,初始化消息源。
    • 预实例化单例 Beans,发布 ContextRefreshedEvent,应用准备就绪。
  • Spring Boot

    • 应用程序调用 SpringApplication.runSpringApplication 通知 SpringApplicationRunListeners 启动。
    • 准备环境,应用 ApplicationContextInitializer
    • 创建和刷新 ApplicationContext,加载自动配置类,注册后处理器。
    • 启动嵌入式 Web 服务器,执行 CommandLineRunnerApplicationRunner
    • 发布 ApplicationReadyEvent,应用准备就绪。

类图对比

以下类图对比展示了 Spring Framework 和 Spring Boot 启动过程中主要类之间的关系。

classDiagram
    %% Spring Framework Classes
    class SF_Application {
        +main(String[] args)
    }

    class SF_AnnotationConfigApplicationContext {
        +register(Class... classes)
        +refresh()
        +getBean(String name)
        +close()
    }

    class SF_DefaultListableBeanFactory {
        +loadBeanDefinitions()
        +preInstantiateSingletons()
    }

    class SF_BeanFactoryPostProcessor {
        +postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory)
    }

    class SF_BeanPostProcessor {
        +postProcessBeforeInitialization(Object bean, String beanName)
        +postProcessAfterInitialization(Object bean, String beanName)
    }

    class SF_MessageSource {
        +getMessage(String code, Object[] args, Locale locale)
    }

    SF_Application --> SF_AnnotationConfigApplicationContext
    SF_AnnotationConfigApplicationContext --> SF_DefaultListableBeanFactory
    SF_AnnotationConfigApplicationContext --> SF_BeanFactoryPostProcessor
    SF_AnnotationConfigApplicationContext --> SF_BeanPostProcessor
    SF_AnnotationConfigApplicationContext --> SF_MessageSource

    %% Spring Boot Classes
    class SB_Application {
        +main(String[] args)
    }

    class SB_SpringApplication {
        +run(Class primarySource, String[] args)
    }

    class SB_SpringApplicationRunListeners {
        +starting()
        +environmentPrepared()
        +contextPrepared()
        +contextLoaded()
        +running()
        +ready()
    }

    class SB_ConfigurableEnvironment {
        +getProperty(String key)
        +setProperty(String key, String value)
    }

    class SB_ApplicationContextInitializer {
        +initialize(ConfigurableApplicationContext context)
    }

    class SB_ConfigurableApplicationContext {
        +refresh()
        +getBean(String name)
        +close()
    }

    class SB_ConfigurableListableBeanFactory {
        +registerBeanDefinition()
        +getBean()
    }

    class SB_AutoConfiguration {
        +@Configuration classes
    }

    class SB_EmbeddedWebServer {
        +start()
        +stop()
    }

    class SB_CommandLineRunner {
        +run(String... args)
    }

    class SB_ApplicationRunner {
        +run(ApplicationArguments args)
    }

    SB_Application --> SB_SpringApplication
    SB_SpringApplication --> SB_SpringApplicationRunListeners
    SB_SpringApplication --> SB_ConfigurableEnvironment
    SB_SpringApplication --> SB_ApplicationContextInitializer
    SB_SpringApplication --> SB_ConfigurableApplicationContext
    SB_SpringApplication --> SB_AutoConfiguration
    SB_SpringApplication --> SB_EmbeddedWebServer
    SB_SpringApplication --> SB_CommandLineRunner
    SB_SpringApplication --> SB_ApplicationRunner

类图对比解释:

  • Spring Framework

    • 主要通过 AnnotationConfigApplicationContext 管理 Bean 的生命周期。
    • 使用 DefaultListableBeanFactory 作为 BeanFactory 实现。
    • 通过注册和应用 BeanFactoryPostProcessorBeanPostProcessor 扩展功能。
  • Spring Boot

    • 主要通过 SpringApplication 启动和管理应用。
    • 使用 SpringApplicationRunListeners 监听启动过程中的各个阶段。
    • 支持自动配置,通过 AutoConfiguration 类自动配置 Bean。
    • 集成嵌入式 Web 服务器,通过 EmbeddedWebServer 启动和管理。
    • 支持 CommandLineRunnerApplicationRunner 接口,在应用启动后执行特定逻辑。

如何使用这些图

上述 Mermaid 语法的代码可以在支持 Mermaid 的编辑器或工具中渲染,例如:

  • Markdown 编辑器:如 VSCode 的 Markdown Preview 插件。
  • 在线 Mermaid 编辑器Mermaid Live Editor
  • 静态网站生成器:如 GitHub Pages 支持的 Mermaid 渲染。

步骤示例:

  1. 复制 Mermaid 代码:选择你感兴趣的流程图、时序图或类图的代码块。
  2. 粘贴到 Mermaid 编辑器:例如,打开 Mermaid Live Editor 并粘贴代码。
  3. 查看渲染结果:编辑器会实时渲染出对应的图形,帮助你更好地理解启动流程。

示例:

将以下代码粘贴到 Mermaid Live Editor 中,可以查看 Spring Boot 的启动流程时序图。

sequenceDiagram
    participant App as Application
    participant SpringApp as SpringApplication
    participant Listeners as SpringApplicationRunListeners
    participant Environment as ConfigurableEnvironment
    participant Initializers as ApplicationContextInitializer
    participant Context as ConfigurableApplicationContext
    participant BeanFactory as ConfigurableListableBeanFactory
    participant AutoConfig as AutoConfiguration
    participant WebServer as EmbeddedWebServer
    participant Runners as CommandLineRunner/ApplicationRunner

    App->>SpringApp: SpringApplication.run(MyApplication.class, args)
    SpringApp->>Listeners: Call runListeners.starting()
    SpringApp->>SpringApp: prepareEnvironment()
    SpringApp->>Environment: Configure Environment (property sources)
    SpringApp->>Listeners: Call runListeners.environmentPrepared()
    SpringApp->>Listeners: Call runListeners.contextPrepared()
    SpringApp->>Initializers: Apply ApplicationContextInitializers
    SpringApp->>SpringApp: createApplicationContext()
    SpringApp->>Context: Instantiate ApplicationContext
    Context->>SpringApp: Configure ApplicationContext
    SpringApp->>Listeners: Call runListeners.contextLoaded()
    SpringApp->>Context: Refresh ApplicationContext
    Context->>BeanFactory: Invoke BeanFactoryPostProcessors
    Context->>Context: Register BeanPostProcessors
    Context->>AutoConfig: Load AutoConfiguration classes
    Context->>Context: Refresh and Initialize Beans
    Context->>WebServer: Start Embedded Web Server
    Context->>Runners: Execute CommandLineRunner/ApplicationRunner
    SpringApp->>Listeners: Call runListeners.running()
    SpringApp->>Listeners: Call runListeners.ready()
    SpringApp-->App: Return ApplicationContext