转载

SpringApplication启动原理

我们知道,如果不需要特殊的配置,只需要在main方法里调用SpringApplicatio.run()方法即可启动Spring Boot应用:

public static void main(String[] args) throws Exception {

SpringApplication.run(Application.class, args);

}

作为深入原理的第一篇,我们先来看下Spring Boot应用是怎么启动的。

SpringBoot简介

SpringBoot是由Pivotal团队提供的全新框架,其设计目的是用来简化新Spring应用的初始搭建以及开发过程。该框架使用了特定的方式来进行配置,从而使开发人员不再需要定义样板化的配置。通过这种方式,Boot致力于在蓬勃发展的快速应用开发领域(rapid application development)成为领导者。

SpringBoot并不是要成为Spring平台里面众多“Foundation”层项目的替代者。SpringBoot的目标不在于为已解决的问题域提供新的解决方案,而是为平台带来另一种开发体验,从而简化对这些已有技术的使用。

SpringBoot主要有如下核心特点:

包含执行所需的一切的可执行jar包。包含了运行所需的一切,包括内嵌应用服务器等,并打包为一个可执行jar文件部署,这点在微服务概念里非常重要。

约定大于配置理念的完美践行,自动配置模块

提供各种各样的starter简化初始配置过程

提供各种扩展机制等等

可以看出,这是一个复合注释,其中

@SpringBootConfiguration代表了SpringBoot的配置类,除了测试时有些区别,大体上就是Spring标准@Configuration的替代品。

@EnableAutoConfiguration用于启动SpringBoot的自动配置机制,这是SpringBoot的核心特色之一,自动对各种机制进最大可能的进行配置。可根据引入的jar包对可能需要的各种机制进进行默认配置。

@ComponentScan是Spring原来就有的注释,用于对指定的路径进行扫描,并将其中的@Configuration配置类加载。

SpringApplication启动流程

SpringApplication的启动过程非常复杂,下面是在调用SpringApplication.run方法之后启动的关键动作:

既然要了解SpringApplication的启动流程,第一步当然是进入源码里看看喽:

第一步,初始化监听器

这里会初始化Spring Boot自带的监听器,以及添加到SpringApplication的自定义监听器。

初始化监听器的调用关系很深,为了节省篇幅,就不贴源码了,稍后用专门的文章细聊。

第二步,发布ApplicationStartedEvent事件

到这一步,Spring Boot会发布一个ApplicationStartedEvent事件。如果你想在这个时候执行一些代码可以通过实现ApplicationListener接口实现;

下面是ApplicationListener接口的定义,注意这里有个<E extends ApplicationEvent>

public interface ApplicationListener<E extends ApplicationEvent> extends EventListener

例如,你想监听ApplicationStartedEvent事件,你可以这样定义:

public class ApplicationStartedListener implements ApplicationListener<ApplicationStartedEvent>

然后通过SpringApplication.addListener(..)添加进去即可。

第三步,装配参数和环境

在这一步,首先会初始化参数,然后装配环境,确定是web环境还是非web环境。

第四步,发布ApplicationEnvironmentPreparedEvent事件

准确的说,这个应该属于第三步,在装配完环境后,就触发ApplicationEnvironmentPreparedEvent事件。如果想在这个时候执行一些代码,可以订阅这个事件的监听器,方法同第二步。

第五步,打印Banner

看过Spring Boot实例教程 - 自定义Banner的同学会很熟悉,启动的Banner就是在这一步打印出来的。

第六步,创建ApplicationContext

这里会根据是否是web环境,来决定创建什么类型的ApplicationContext,ApplicationContext不要多说了吧,不知道ApplicationContext是啥的同学,出门左转补下Spring基础知识吧。

第七步,装配Context

这里会设置Context的环境变量、注册Initializers、beanNameGenerator等。

第八步,发布ApplicationPreparedEvent事件

这里放在第七步会更准确,因为这个是在装配Context的时候发布的。

值得注意的是:这里是假的,假的,假的,源码中是空的,并没有真正发布ApplicationPreparedEvent事件。不知道作者这么想的???

第九步,注册、加载等

注册springApplicationArguments、springBootBanner,加载资源等。

第十步,发布ApplicationPreparedEvent事件

注意,到这里才是真正发布了ApplicationPreparedEvent事件。这里和第八步好让人误解。

第十一步,refreshContext

装配context beanfactory等非常重要的核心组件。

第十二步,afterRefreshContext

这里会调用自定义的Runners,不知道Runners是什么的同学,请参考Spring Boot官方文档 - SpringApplication

第十三步,发布ApplicationReadyEvent事件

最后一步,发布ApplicationReadyEvent事件,启动完毕,表示服务已经可以开始正常提供服务了。通常我们这里会监听这个事件来打印一些监控性质的日志,表示应用正常启动了。添加方法同第二步。

注意:如果启动失败,这一步会发布ApplicationFailedEvent事件。

到这里,Spring Boot启动的一些关键动作就介绍完了。

原文  https://segmentfault.com/a/1190000021168232
正文到此结束
Loading...