Spring Boot(二) SpringApplication执行流程

一、静态run方法受限建立一个SpringApplication实例,而后调用其run方法web

SpringApplication实例化,会作:spring

·根据classpath里面是否存在某个特征类(org.springframework.web.context.ConfigurableWebApplicationContext)来决定是否应该建立一个为Web应用使用的ApplicationContext类型,仍是应该建立一个标准Standalone应用使用的使用的ApplicationContext类型,仍是应该建立一个标准Standalone应用使用的ApplicationContext类型。
·使用SpringFactoriesLoader在应用的classpath中查找并加载全部可用的ApplicationContextInitializer。
·使用SpringFactoriesLoader在应用的classpath中查找并加载全部可用的ApplicationListener。
·推断并设置main方法的定义类app

二、run方法执行开始,首先遍历执行全部经过SpringFactoriesLoader能够查找到并加载的SpringApplicationRunListener,调用它们的started()方法框架

三、建立并配置当前SpringBoot应用将要使用的Environment(包括配置要使用的PropertySource以及Profile)。
四、遍历调用全部SpringApplicationRunListener的environmentPrepared()的方法
五、若是SpringApplication的showBanner属性被设置为true,则打印bannerspa

六、根据用户是否明确设置了applicationContextClass类型以及初始化阶段的推断结果,决定该为当前SpringBoot应用建立什么类型的ApplicationContext并建立完成,而后根据条件决定是否添加ShutdownHook,决定是否使用自定义的BeanNameGenerator,决定是否使用自定义的ResourceLoader,固然,最重要的,将以前准备好的Environment设置给建立好的ApplicationContext使用。
七、ApplicationContext建立好以后,SpringApplication会再次借助Spring-FactoriesLoader,查找并加载classpath中全部可用的ApplicationContext-Initializer,而后遍历调用这些ApplicationContextInitializer的initialize(applicationContext)方法来对已经建立好的ApplicationContext进行进一步的处理。
八、遍历调用全部SpringApplicationRunListener的contextPrepared()方法接口

九、最核心的一步,将以前经过@EnableAutoConfiguration获取的全部配置以及其余形式的IoC容器配置加载到已经准备完毕的ApplicationContext。事件

十、遍历调用全部SpringApplicationRunListener的contextLoaded()方法开发

十一、调用ApplicationContext的refresh()方法,完成IoC容器可用的最后一道工序。
十二、查找当前ApplicationContext中是否注册有CommandLineRunner,若是有,则遍历执行它们。
1三、正常状况下,遍历执行SpringApplicationRunListener的finished()方法、(若是整个过程出现异常,则依然调用全部SpringApplicationRunListener的finished()方法,只不过这种状况下会将异常信息一并传入处理)it

去除事件通知点后,整个流程以下:io

SpringApplicationRunListener

SpringApplicationRunListener是一个只有SpringBoot应用的main方法执行过程当中接收不一样执行时点事件通知的监听者。基本没什么常见的场景须要本身实现一个Spring-ApplicationRunListener,即便SpringBoot默认也只是实现了一个org.spring-framework.boot.context.event.EventPublishingRunListener,用于在SpringBoot启动的不一样时点发布不一样的应用事件类型(ApplicationEvent)

ApplicationListener

Spring框架对Java中实现的监听者模式的一种框架实现,这里惟一值得着重强调的是,对于初次接触SpringBoot,但对Spring框架自己又没有过多接触的开发者来讲,可能会将这个名字与SpringApplicationRunListener混淆

若是咱们要为SpringBoot应用添加自定义的ApplicationListener,有两种方式:
1)经过SpringApplication.addListeners(..)或者SpringApplication.setListeners(..)方法添加一个或者多个自定义的ApplicationListener;
2)借助SpringFactoriesLoader机制,在META-INF/spring.factories文件添加配置

ApplicationContextInitializer

ApplicationContextInitializer也是Spring框架原有的概念,这个类的主要目的就是在ConfigurableApplicationContext类型(或者子类型)的ApplicationContext作refresh以前,容许咱们对ConfigurableApplicationContext的实例作进一步的设置或者处理

通常状况下咱们基本不会须要自定义一个ApplicationContext-Initializer,即便SpringBoot框架默认也只是注册了三个实现。若是咱们真的须要自定义一个ApplicationContextInitializer,那么只要像上面这样,经过SpringFactoriesLoader机制进行配置,或者经过SpringApplication.addInitializers(..)设置便可

CommandLineRunner

属于SpringBoot应用特定的回调扩展接口

须要你们关注的其实就两点:
1)全部CommandLineRunner的执行时点在SpringBoot应用的Application-Context彻底初始化开始工做以后(能够认为是main方法执行完成以前最后一步)。
2)只要存在于当前SpringBoot应用的ApplicationContext中的任何Command-LineRunner,都会被加载执行(无论你是手动注册这个CommandLineRunner到IoC容器,仍是自动扫描进去的)

与其余几个扩展点接口类型类似,建议CommandLineRunner的实现类使用@org.springframework.core.annotation.Order进行标注或者实现org.springframework.core.Ordered接口,便于对它们的执行顺序进行调整,这其实十分重要,咱们不但愿顺序不当的CommandLineRunner实现类阻塞了后面其余CommandLineRunner的执行。 CommandLineRunner是很好的扩展接口,你们能够重点关注

相关文章
相关标签/搜索