面试官:知道 springboot 的启动原理吗?

springboot 启动原理springboot 常见的启动写法如下:
@SpringBootApplicationpublic class Application {    public static void main(String[] args) {        SpringApplication.run(Application.class, args);    }}然后我们的程序就可以和 main 方法一样,直接启动运行了 。
【面试官:知道 springboot 的启动原理吗?】但是这一切是如何实现的呢?
今天我们一起来学习一下 springboot 的启动原理 。
SpringApplication.run 方法main 方法整体看起来看起来平平无奇 。
平平无奇
SpringApplication.run() 让我意识到问题并不简单,我们一起看一下 run 里面到底是如何实现的 。
public static ConfigurableApplicationContext run(Object source, String... args) {    return run(new Object[] { source }, args);}这里调用了另外一个方法:
public static ConfigurableApplicationContext run(Object[] sources, String[] args) {    return new SpringApplication(sources).run(args);}这里实际上是创建了 SpringApplication 对象,并且执行 run 方法 。
SpringApplication我们简单看一下这个对象 。
public SpringApplication(Object... sources) {    initialize(sources);}这里主要是针对 spring 的初始化:
private void initialize(Object[] sources) {    if (sources != null && sources.length > 0) {        this.sources.addAll(Arrays.asList(sources));    }    this.webEnvironment = deduceWebEnvironment();    setInitializers((Collection) getSpringFactoriesInstances(            ApplicationContextInitializer.class));    setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));    this.mainApplicationClass = deduceMainApplicationClass();}设置了一些初始化实现、监听器等,此处不做详细展开 。
run 方法构建完成之后,需要调用对应的 run 方法,这个方法是比较复杂的,不过也不用太紧张,有兴趣的可以深入研究一下 。
/** * Run the Spring application, creating and refreshing a new * {@link ApplicationContext}. * @param args the application arguments (usually passed from a JAVA main method) * @return a running {@link ApplicationContext} */public ConfigurableApplicationContext run(String... args) {    StopWatch stopWatch = new StopWatch();    stopWatch.start();    ConfigurableApplicationContext context = null;    FailureAnalyzers analyzers = null;    configureHeadlessProperty();    SpringApplicationRunListeners listeners = getRunListeners(args);    listeners.starting();    try {        ApplicationArguments applicationArguments = new DefaultApplicationArguments(                args);        ConfigurableEnvironment environment = prepareEnvironment(listeners,                applicationArguments);        Banner printedBanner = printBanner(environment);        context = createApplicationContext();        analyzers = new FailureAnalyzers(context);        prepareContext(context, environment, listeners, applicationArguments,                printedBanner);        refreshContext(context);        afterRefresh(context, applicationArguments);        listeners.finished(context, null);        stopWatch.stop();        if (this.logStartupInfo) {            new StartupInfoLogger(this.mainApplicationClass)                    .logStarted(getApplicationLog(), stopWatch);        }        return context;    }    catch (Throwable ex) {        handleRunFailure(context, listeners, analyzers, ex);        throw new IllegalStateException(ex);    }}


推荐阅读