Spring Boot 启动源码解析系列六:执行启动方法一

1234567891011121314151617181920212223242526272829303132333435363738394041424344
public ConfigurableApplicationContext (String... args) {

    StopWatch stopWatch = new StopWatch();    // 开始执行,记录开始时间    stopWatch.start();

    ConfigurableApplicationContext context = null;    FailureAnalyzers analyzers = null;    this.configureHeadlessProperty();

    // 获取 SpringApplicationRunListener 实现类,实际只有 EventPublishingRunListener 一个实现类    SpringApplicationRunListeners listeners = this.getRunListeners(args);    // ApplicationStartedEvent 事件监听器执行监听    listeners.starting();

    try {        // 实例化应用程序参数持有类        ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);        // 实例化容器环境配置信息        ConfigurableEnvironment environment = this.prepareEnvironment(listeners, applicationArguments);

        // 打印 Banner        Banner printedBanner = this.printBanner(environment);

        // 实例化 Spring ApplicationContext         context = this.createApplicationContext();        new FailureAnalyzers(context);        this.prepareContext(context, environment, listeners, applicationArguments, printedBanner);        this.refreshContext(context);        this.afterRefresh(context, applicationArguments);

        //         listeners.finished(context, (Throwable)null);        stopWatch.stop();        if (this.logStartupInfo) {            (new StartupInfoLogger(this.mainApplicationClass)).logStarted(this.getApplicationLog(), stopWatch);        }

        return context;    } catch (Throwable var9) {        this.handleRunFailure(context, listeners, (FailureAnalyzers)analyzers, var9);        throw new IllegalStateException(var9);    }}

核心步骤一:启动 SpringApplicationRunListener

12
SpringApplicationRunListeners listeners = this.getRunListeners(args);listeners.starting();

SpringApplicationRunListener 接口:

1234567891011
public interface SpringApplicationRunListener {    void starting();

    void environmentPrepared(ConfigurableEnvironment var1);

    void contextPrepared(ConfigurableApplicationContext var1);

    void contextLoaded(ConfigurableApplicationContext var1);

    void finished(ConfigurableApplicationContext var1, Throwable var2);}

SpringApplicationRunListener 接口目前只有 EventPublishingRunListener 一个实现类。

1234
private SpringApplicationRunListeners getRunListeners(String[] args) {    Class<?>[] types = new Class[]{SpringApplication.class, String[].class};    return new SpringApplicationRunListeners(logger, this.getSpringFactoriesInstances(SpringApplicationRunListener.class, types, this, args));}

同理也是实例化 SpringApplicationRunListener 接口实现类,最终实际是调用 EventPublishingRunListener 的 starting() 方法:

123
public void starting() {    this.initialMulticaster.multicastEvent(new ApplicationStartedEvent(this.application, this.args));}

最终调用:

12345678910111213141516171819
public void multicastEvent(final ApplicationEvent event, ResolvableType eventType) {    ResolvableType type = eventType != null ? eventType : this.resolveDefaultEventType(event);    Iterator var4 = this.getApplicationListeners(event, type).iterator();

    while(var4.hasNext()) {        final ApplicationListener<?> listener = (ApplicationListener)var4.next();        Executor executor = this.getTaskExecutor();        if (executor != null) {            executor.execute(new Runnable() {                public void () {                    SimpleApplicationEventMulticaster.this.invokeListener(listener, event);                }            });        } else {            this.invokeListener(listener, event);        }    }

}

SpringApplicationRunListener 会被构建为 AppicationEvent,然后被 ApplicationEventMulticaster 广播,最后转变为 ApplicationListener。

这中间比较复杂,看的也不是特别的深入,后续继续深入分析。

原文:大专栏  Spring Boot 启动源码解析系列六:执行启动方法一

原文地址:https://www.cnblogs.com/chinatrump/p/11611938.html

时间: 2024-08-27 03:46:12

Spring Boot 启动源码解析系列六:执行启动方法一的相关文章

Feign 系列(05)Spring Cloud OpenFeign 源码解析

Feign 系列(05)Spring Cloud OpenFeign 源码解析 [TOC] Spring Cloud 系列目录(https://www.cnblogs.com/binarylei/p/11563952.html#feign) 在 上一篇 文章中我们分析 Feign 参数解析的整个流程,Feign 原生已经支持 Feign.JAX-RS 1/2 声明式规范,本文着重关注 Spring Cloud 是如果整合 OpenFeign 的,使之支持 Spring MVC? 1. Sprin

Spring Security 解析(七) —— Spring Security Oauth2 源码解析

Spring Security 解析(七) -- Spring Security Oauth2 源码解析 ??在学习Spring Cloud 时,遇到了授权服务oauth 相关内容时,总是一知半解,因此决定先把Spring Security .Spring Security Oauth2 等权限.认证相关的内容.原理及设计学习并整理一遍.本系列文章就是在学习的过程中加强印象和理解所撰写的,如有侵权请告知. 项目环境: JDK1.8 Spring boot 2.x Spring Security

【原】Android热更新开源项目Tinker源码解析系列之二:资源文件热更新

上一篇文章介绍了Dex文件的热更新流程,本文将会分析Tinker中对资源文件的热更新流程. 同Dex,资源文件的热更新同样包括三个部分:资源补丁生成,资源补丁合成及资源补丁加载. 本系列将从以下三个方面对Tinker进行源码解析: Android热更新开源项目Tinker源码解析系列之一:Dex热更新 Android热更新开源项目Tinker源码解析系列之二:资源热更新 Android热更新开源项目Tinker源码解析系类之三:so热更新 转载请标明本文来源:http://www.cnblogs

Backbone源码解析系列

01 编码风格.继承 02 Backbone.Events 03 Backbone.Model 04 Backbone.View 05 Backbone.Router 06 Backbone应用于web交互型应用 07 Backbone应用于移动终端应用 Backbone源码解析系列,布布扣,bubuko.com

【原】Android热更新开源项目Tinker源码解析系列之三:so热更新

本系列将从以下三个方面对Tinker进行源码解析: Android热更新开源项目Tinker源码解析系列之一:Dex热更新 Android热更新开源项目Tinker源码解析系列之二:资源文件热更新 Android热更新开源项目Tinker源码解析系类之三:so文件热更新 转载请标明本文来源:http://www.cnblogs.com/yyangblog/p/6252855.html更多内容欢迎star作者的github:https://github.com/LaurenceYang/artic

异步任务spring @Async注解源码解析

1.引子 开启异步任务使用方法: 1).方法上加@Async注解 2).启动类或者配置类上@EnableAsync 2.源码解析 虽然spring5已经出来了,但是我们还是使用的spring4,本文就根据spring-context-4.3.14.RELEASE.jar来分析源码. 2.1.@Async org.springframework.scheduling.annotation.Async 源码注释翻译: 1 /** 2 * Annotation that marks a method

Spring @Import注解源码解析

简介 Spring 3.0之前,创建Bean可以通过xml配置文件与扫描特定包下面的类来将类注入到Spring IOC容器内.而在Spring 3.0之后提供了JavaConfig的方式,也就是将IOC容器里Bean的元信息以java代码的方式进行描述.我们可以通过@Configuration与@Bean这两个注解配合使用来将原来配置在xml文件里的bean通过java代码的方式进行描述 @Import注解提供了@Bean注解的功能,同时还有xml配置文件里标签组织多个分散的xml文件的功能,当

Android源码解析系列

Android异步消息处理机制(2)源码解析 版权声明:本文为博主原创文章,未经博主允许不得转载.

SpringMvc启动源码解析

1. 前言 上篇文章介绍了Spring容器的初始化https://www.cnblogs.com/xiaobingblog/p/11738747.html,接下来介绍SpringMvc容器的初始化 2. 初始化化过程 上文讲过一个Web项目的启动在加载listener.fliter初始化后,再进行servlet初始化.那SpringMvc如何与Servlet联系起来?看web.xml配置文件,有一个专门配置SpringMvc的servlet,就是DispatcherServlet.看下Dispa