13. 扩展:SpringApplication的执行流程
SpringApplication 将一个典型的 Spring 应用启动的流程“模板化”(这里是动词),在没有特殊需求的情况下,默认模板化后的执行流程就可以满足需求了但有特殊需求也没关系,SpringApplication 在合适的流程结点开放了一系列不同类型的扩展点,我们可以通过这些扩展点对 SpringBoot 程序的启动和关闭过程进行扩展。
最“肤浅”的扩展或者配置是 SpringApplication 通过一系列设置方法(setters)开放的定制方式,比如,我们之前的启动类的 main 方法中只有一句:
SpringApplication.run(DemoApplication.class,args);
但如果我们想通过 SpringApplication 的一系列设置方法来扩展启动行为,则可以用如下方式进行:
public class DemoApplication {
public static void main(String[] args) {
// SpringApplication.run(DemoConfiguration.class, args);
SpringApplication bootstrap = new SpringApplication(Demo - Configuration.class);
bootstrap.setBanner(new Banner() {
@Override
public void printBanner(Environment environment, Class<?> aClass, PrintStream printStream) {
// 比如打印一个我们喜欢的ASCII Arts字符画
}
});
bootstrap.setBannerMode(Banner.Mode.CONSOLE);
// 其他定制设置...
bootstrap.run(args);
}
}
设置自定义 banner 最简单的方式其实是把 ASCII Art 字符画放到一个资源文件,然后通过 ResourceBanner 来加载:
bootstrap.setBanner(new ResourceBanner(new ClassPathResource("banner.txt")));
大部分情况下,SpringApplication 已经提供了很好的默认设置,所以,我们不再对这些表层进行探究了,因为对表层之下的东西进行探究才是我们的最终目的。
深入探索 SpringApplication 执行流程
SpringApplication 的 run 方法的实现是我们本次旅程的主要线路,该方法的主要流程大体可以归纳如下:
1)如果我们使用的是 SpringApplication 的静态 run 方法,那么,这个方法里面首先需要创建一个 SpringApplication 对象实例,然后调用这个创建好的 SpringApplication 的实例 run方 法。在 SpringApplication 实例初始化的时候,它会提前做几件事情:
根据 classpath 里面是否存在某个特征类(org.springframework.web.context.ConfigurableWebApplicationContext)来决定是否应该创建一个为 Web 应用使用的 ApplicationContext 类型,还是应该创建一个标准 Standalone 应用使用的 ApplicationContext 类型。
使用 SpringFactoriesLoader 在应用的 classpath 中查找并加载所有可用的 ApplicationContextInitializer。
使用 SpringFactoriesLoader 在应用的 classpath 中查找并加载所有可用的 A