项目初始化启动过程大致包括以下部分:
– 第一步:获取并启动监听器
this.getRunListeners(args) 和 listeners.starting() 方法主要用于获取 SpringApplication 实例初始化过程中初始化的 SpringApplicationRunListener 监听器并运行。
– 第二步:根据 SpringApplicationRunListeners 以及参数来准备环境
this.prepareEnvironment(listeners, applicationArguments) 方法主要用于对项目运行环境进行预设置,同时通过 this.configureIgnoreBeanInfo(environment) 方法排除一些不需要的运行环境
– 第三步:创建 Spring 容器
根据 webApplicationType 进行判断,确定容器类型,如果该类型为 SERVLET 类型,会通过反射装载对应的字节码,也就是 AnnotationConfigServletWebServerApplicationContext,接着使用之前初始化设置的 context(应用上下文环境)、environment(项目运行环境)、listeners(运行监听器)、applicationArguments(项目参数)和 printedBanner(项目图标信息)进行应用上下文的组装配置,并刷新配置
– 第四步:Spring 容器前置处理
这一步主要是在容器刷新之前的准备动作。设置容器环境,包括各种变量等等,其中包含一个非常关键的操作:将启动类注入容器,为后续开启自动化配置奠定基础
– 第五步:刷新容器
开启刷新 spring 容器,通过 refresh 方法对整个 IOC 容器的初始化 (包括 bean 资源的定位,解析,注册等等),同时向 JVM 运行时注册一个关机钩子,在 JVM 关机时会关闭这个上下文,除非当时它已经关闭
– 第六步:Spring 容器后置处理
扩展接口,设计模式中的模板方法,默认为空实现。如果有自定义需求,可以重写该方法。比如打印一些启动结束 log,或者一些其它后置处理。
– 第七步:发出结束执行的事件
获取 EventPublishingRunListener 监听器,并执行其 started 方法,并且将创建的 Spring 容器传进去了,创建一个 ApplicationStartedEvent 事件,并执行 ConfigurableApplicationContext 的 publishEvent 方法,也就是说这里是在 Spring 容器中发布事件,并不是在 SpringApplication 中发布事件,和前面的 starting 是不同的,前面的 starting 是直接向 SpringApplication 中的监听器发布启动事件。
– 第八步:执行 Runners
用于调用项目中自定义的执行器 XxxRunner 类,使得在项目启动完成后立即执行一些特定程序。其中,Spring Boot 提供的执行器接口有 ApplicationRunner 和 CommandLineRunner 两种,在使用时只需要自定义一个执行器类实现其中一个接口并重写对应的 run() 方法接口,然后 Spring Boot 项目启动后会立即执行这些特定程序
这些内容,是从拉勾教育的《Java 工程师高薪训练营》里学到的,课程内容非常全面,还有拉勾的内推大厂服务,推荐你也看看。