SpringBoot启动过程

Spring Boot的启动过程实际上是相当复杂的,涉及大量的组件、自动配置和钩子。下面是一个更加详细的列表,描述了Spring Boot启动时会发生的主要步骤:

  1. 启动入口:Spring Boot应用的启动从main方法开始,通常在这个方法里会调用SpringApplication.run()

  2. 创建SpringApplication对象run()方法首先创建一个SpringApplication对象,该对象包含了应用的主要配置,如启动的类、资源和环境信息。

  3. 初始化启动参数:解析命令行参数,准备用于Spring Boot运行环境的参数。

  4. 设置初始化器(Initializers):设置并调用ApplicationContextInitializer,它可以在ConfigurableApplicationContext类型的上下文完全初始化前对其进行配置或修改。

  5. 设置监听器(Listeners):设置并调用ApplicationListener,用于响应各种应用事件,包括启动过程中的一系列事件。

  6. 推断应用的类型:根据类路径中的存在的类(例如是否存在ServletContext类),推断应用是普通的Spring应用还是Web应用。

  7. 准备环境:准备SpringApplication的运行环境,包括配置默认的配置源(properties文件)、环境变量和命令行参数等。对于Web应用,还会根据不同的Web环境(Reactive, Servlet)准备不同的Web运行环境。

  8. 打印Banner:如果配置了Banner(在src/main/resources下的banner.txt或通过代码设置),此时输出。

  9. 创建应用上下文:依据推断结果,创建合适类型的Spring应用上下文(ApplicationContext),比如AnnotationConfigServletWebServerApplicationContextAnnotationConfigApplicationContext

  10. 初始化应用上下文:调用之前设置的ApplicationContextInitializerinitialize方法,允许用户自定义上下文的初始化。

  11. 应用上下文准备事件:发布ApplicationStartedEventApplicationEnvironmentPreparedEvent事件,允许相应地修改环境或者提前执行某些动作。

  12. 加载Bean定义:根据@SpringBootApplication(包含@ComponentScan)和其他配置类,加载应用中的Bean定义。

  13. 执行自动配置:根据spring.factories文件中的配置,执行自动配置类,自动配置类会根据条件(@Conditional注解)确定是否加载。

  14. 刷新应用上下文:刷新上下文,完成Bean的创建、依赖注入、初始化等工作。

  15. 执行命令行运行器:调用实现了CommandLineRunnerApplicationRunner接口Bean的run方法。

  16. 应用准备完成事件:发布ApplicationReadyEvent,表示应用已准备好接收请求。

  17. 启动内嵌服务器:如果是Web应用,此时启动内嵌的Web服务器(如Tomcat、Jetty或Undertow),并初始化DispatchServlet。

  18. 等待应用退出SpringApplication.run()结束,应用继续运行,直到收到停止命令,则进行清理并关闭上下文。

这个列表提供了Spring Boot启动过程的一个相当详尽的视角,但是实际上在实际的应用中,基于不同的配置和自定义的组件,还可能涉及更多的步骤和细节。

在Spring Boot中,ApplicationContextInitializerApplicationListener是在Spring容器的生命周期的早期阶段运行的回调接口,用于定制化容器的启动过程。由于它们运行的时间点较早,容器可能还没有完全初始化,许多Bean可能还未被创建和注册,因此在这些组件中使用@Autowired注入其他的Bean通常是不可行的或者说行为是不确定的。

对于ApplicationContextInitializer,它直接操作ApplicationContext的配置,这发生在容器的Bean定义被加载之前,因此此时容器里面还没有Bean可以被注入。

对于ApplicationListener,如果监听器是通过Spring的组件扫描(即带有@Component等注解)被注册成一个Bean的话,那么它将像其他Spring管理的Bean一样,可以使用@Autowired来注入依赖。不过,需要注意的是不所有的ApplicationListener都会被注册为Bean,有些可以在application.properties中通过context.listener.classes配置,或者在META-INF/spring.factories文件中通过org.springframework.context.ApplicationListener配置,这些监听器不会成为容器管理的Bean,因此也就不支持@Autowired注入。

如果您想在ApplicationListener中注入其他Bean,并且要确保此时这些Bean已经被创建,您可能需要监听一个如ContextRefreshedEvent的稍晚发生的事件。此时ApplicationContext已经刷新完毕,容器内的Bean已经准备就绪,可以被安全地注入。

总体来说,您应该非常小心地在ApplicationContextInitializer和ApplicationListener中注入依赖,确保这些操作在Spring容器生命周期的正确阶段内进行。如果您需要注入依赖来完成某些配置或启动任务,可能更适合使用标准的Spring Bean生命周期回调如@PostConstruct或者实现InitializingBean接口。对于处理特定事件,您可以考虑使用ApplicationEvent机制并确保在合适的时间点进行依赖注入。

附:Spring Boot 内置的 Application Event
(1)Spring Boot 中包含了一些与 SpringApplication 生命周期相关的内置 Application Event,包括:

ApplicationStartingEvent:在 Spring Boot 应用程序启动之前发布。
ApplicationEnvironmentPreparedEvent:在 Spring Boot 应用程序的环境已经准备好,但正在创建 Application Context 上下文之前发布。
ApplicationContextInitializedEvent:当 Spring Boot 应用程序 Application Context 上下文准备就绪并且调用
ApplicationContextInitializers,但尚未加载 bean 定义时发布。
ApplicationPreparedEvent:在 Spring Boot 应用程序的 Application Context 上下文已经创建,但尚未刷新之前发布。
ApplicationStartedEvent:在 Spring Boot 应用程序的 Application Context 上下文已经刷新,但尚未启动之前发布。
ApplicationReadyEvent:在 Spring Boot 应用程序已经启动并准备接受请求之后发布。
ApplicationFailedEvent:在 Spring Boot 应用程序启动失败时发布。

参考:

Springboot启动流程分析(二):准备IOC容器相关信息_springboot this.preparecontext(context, environmen-CSDN博客

  • 16
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

济南大飞哥

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值