spring-boot-2.0.3不一样系列之源码篇 - run方法(三)之createApplicationContext,绝对有值得你看的地方

  此系列是针对springboot的启动,旨在于和大家一起来看看springboot启动的过程中到底做了一些什么事。如果大家对springboot的源码有所研究,可以挑些自己感兴趣或者对自己有帮助的看;但是如果大家没有研究过springboot的源码,不知道springboot在启动过程中做了些什么,那么我建议大家从头开始一篇一篇按顺序读该系列,不至于从中途插入,看的有些懵懂。当然,文中讲的不对的地方也欢迎大家指出,有待改善的地方也希望大家不吝赐教。老规矩:一周至少一更,中途会不定期的更新一些其他的博客,可能是springboot的源码,也可能是其他的源码解析,也有可能是其他的。

  路漫漫其修远兮,吾将上下而求索!

  github:https://github.com/youzhibing

  码云(gitee):https://gitee.com/youzhibing

前情回顾

  大家还记得上篇博文讲了什么吗,或者说大家知道上篇博文讲了什么吗。这里帮大家做个简单回顾,主要做了两件事

  1、加载外部化配置的资源到environment

    包括命令行参数、servletConfigInitParams、servletContextInitParams、systemProperties、sytemEnvironment、random、application.yml(.yaml/.xml/.properties),如下所示

spring-boot-2.0.3不一样系列之源码篇 - run方法(三)之createApplicationContext,绝对有值得你看的地方

  2、广播ApplicationEnvironmentPreparedEvent事件,触发相应的监听器

    ConfigFileApplicationListener

      添加名叫random的RandomValuePropertySource到environment

      添加名叫applicationConfig:[classpath:/application.yml]的OriginTrackedMapPropertySource到environment

    LoggingApplicationListener

      初始化日志系统

createApplicationContext

  先欣赏下我们的战绩,看看我们对run方法完成了多少的源码解读

spring-boot-2.0.3不一样系列之源码篇 - run方法(三)之createApplicationContext,绝对有值得你看的地方

spring-boot-2.0.3不一样系列之源码篇 - run方法(三)之createApplicationContext,绝对有值得你看的地方

/** * 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(); // spring应用上下文,也就是我们所说的spring根容器 ConfigurableApplicationContext context = null; // 自定义SpringApplication启动错误的回调接口 Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList<>(); // 设置jdk系统属性java.awt.headless,默认情况为true即开启 configureHeadlessProperty(); // 获取启动时监听器(EventPublishingRunListener实例) SpringApplicationRunListeners listeners = getRunListeners(args) // 触发ApplicationStartingEvent事件,启动监听器会被调用,一共5个监听器被调用,但只有两个监听器在此时做了事 listeners.starting(); try { // 参数封装,也就是在命令行下启动应用带的参数,如--server.port=9000 ApplicationArguments applicationArguments = new DefaultApplicationArguments( args); // 准备环境:1、加载外部化配置的资源到environment;2、触发ApplicationEnvironmentPreparedEvent事件 ConfigurableEnvironment environment = prepareEnvironment(listeners, applicationArguments); // 配置spring.beaninfo.ignore,并添加到名叫systemProperties的PropertySource中;默认为true即开启 configureIgnoreBeanInfo(environment); // 打印banner图 Banner printedBanner = printBanner(environment); // 创建应用上下文,这是本文重点 context = createApplicationContext(); exceptionReporters = getSpringFactoriesInstances( SpringBootExceptionReporter.class, new Class[] { ConfigurableApplicationContext.class }, context); prepareContext(context, environment, listeners, applicationArguments, printedBanner); refreshContext(context); afterRefresh(context, applicationArguments); stopWatch.stop(); if (this.logStartupInfo) { new StartupInfoLogger(this.mainApplicationClass) .logStarted(getApplicationLog(), stopWatch); } listeners.started(context); callRunners(context, applicationArguments); } catch (Throwable ex) { handleRunFailure(context, ex, exceptionReporters, listeners); throw new IllegalStateException(ex); } try { listeners.running(context); } catch (Throwable ex) { handleRunFailure(context, ex, exceptionReporters, null); throw new IllegalStateException(ex); } return context; }

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zydzgx.html