SpringBoot的启动流程

大神可以一笑而过!有问题欢迎指正下!感激!

在这里插入图片描述

首先看源码得知,开启springboot的main方法中的关键代码
SpringApplication.run(当前类.class,args);
等价于
new SpringApplication(当前类.class).run(args);
所以以后遇到2种写法中的另一种就不要奇怪了。

流程:

  1. SpringApplication 实例对象构造方法初始化

  2. 走到run()里
    ①创建并启动计时监控类

         StopWatch stopWatch = new StopWatch();
         stopWatch.start();
    

    ②初始化应用上下文和异常报告集合

         ConfigurableApplicationContext context = null;
         Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList<>();
    

    ③设置系统属性 java.awt.headless 的值,默认值为:true

         configureHeadlessProperty();
    

    Java.awt.headless = true 有什么作用?
    对于一个 Java 服务器来说经常要处理一些图形元素,例如地图的创建或者图形和图表等。这些API基本上总是需要运行一个X-server以便能使用AWT(Abstract Window Toolkit,抽象窗口工具集)。然而运行一个不必要的 X-server 并不是一种好的管理方式。有时你甚至不能运行 X-server,因此最好的方案是运行 headless 服务器,来进行简单的图像处理。
    参考:www.cnblogs.com/princessd8251/p/4000016.html

    ④创建所有 Spring 运行监听器并发布应用启动事件

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

    创建逻辑和之前实例化初始化器和监听器的一样,一样调用的是 getSpringFactoriesInstances 方法来获取配置的监听器名称并实例化所有的类。

    SpringApplicationRunListener 所有监听器配置在 spring-boot-2.0.3.RELEASE.jar!/META-INF/spring.factories 这个配置文件里面。

     # Run Listeners
     org.springframework.boot.SpringApplicationRunListener=\
     org.springframework.boot.context.event.EventPublishingRunListener
    

⑤初始化默认应用参数类

ApplicationArguments applicationArguments = new DefaultApplicationArguments(
    args);

⑥根据运行监听器和应用参数来准备 Spring 环境

ConfigurableEnvironment environment = prepareEnvironment(listeners,
        applicationArguments);
configureIgnoreBeanInfo(environment);

⑦创建 Banner 打印类

Banner printedBanner = printBanner(environment);

⑧创建应用上下文

context = createApplicationContext();

其实就是根据不同的应用类型初始化不同的上下文应用类。

⑨准备异常报告器

exceptionReporters = getSpringFactoriesInstances(
        SpringBootExceptionReporter.class,
        new Class[] { ConfigurableApplicationContext.class }, context);

逻辑和之前实例化初始化器和监听器的一样,一样调用的是 getSpringFactoriesInstances 方法来获取配置的异常类名称并实例化所有的异常处理类。

该异常报告处理类配置在 spring-boot-2.0.3.RELEASE.jar!/META-INF/spring.factories 这个配置文件里面。

# Error Reporters
org.springframework.boot.SpringBootExceptionReporter=\
org.springframework.boot.diagnostics.FailureAnalyzers

⑩准备应用上下文

prepareContext(context, environment, listeners, applicationArguments,
        printedBanner);	

来看下 prepareContext() 方法的源码:

private void prepareContext(ConfigurableApplicationContext context,
        ConfigurableEnvironment environment, SpringApplicationRunListeners listeners,
        ApplicationArguments applicationArguments, Banner printedBanner) {
    // 10.1)绑定环境到上下文
    context.setEnvironment(environment);

    // 10.2)配置上下文的 bean 生成器及资源加载器
    postProcessApplicationContext(context);

    // 10.3)为上下文应用所有初始化器
    applyInitializers(context);

    // 10.4)触发所有 SpringApplicationRunListener 监听器的 contextPrepared 事件方法
    listeners.contextPrepared(context);

    // 10.5)记录启动日志
    if (this.logStartupInfo) {
        logStartupInfo(context.getParent() == null);
        logStartupProfileInfo(context);
    }

    // 10.6)注册两个特殊的单例bean
    context.getBeanFactory().registerSingleton("springApplicationArguments",
            applicationArguments);
    if (printedBanner != null) {
        context.getBeanFactory().registerSingleton("springBootBanner", printedBanner);
    }

    // 10.7)加载所有资源
    Set<Object> sources = getAllSources();
    Assert.notEmpty(sources, "Sources must not be empty");
    load(context, sources.toArray(new Object[0]));

    // 10.8)触发所有 SpringApplicationRunListener 监听器的 contextLoaded 事件方法
    listeners.contextLoaded(context);   
}

⑩① 刷新应用上下文

refreshContext(context);

⑩②应用上下文刷新后置处理

afterRefresh(context, applicationArguments);

看了下这个方法的源码是空的,目前可以做一些自定义的后置处理操作。

/**
 * Called after the context has been refreshed.
 * @param context the application context
 * @param args the application arguments
 */
protected void afterRefresh(ConfigurableApplicationContext context,
        ApplicationArguments args) {
}

⑩③停止计时监控类

stopWatch.stop();

⑩④输出日志记录执行主类名、时间信息

if (this.logStartupInfo) {
    new StartupInfoLogger(this.mainApplicationClass)
            .logStarted(getApplicationLog(), stopWatch);
}

⑩⑤ 发布应用上下文启动完成事件

listeners.started(context);

触发所有 SpringApplicationRunListener 监听器的 started 事件方法。

⑩⑥ 执行所有 Runner 运行器

callRunners(context, applicationArguments);

执行所有 ApplicationRunner 和 CommandLineRunner 这两种运行器,不详细展开了。

⑩⑦ 发布应用上下文就绪事件

listeners.running(context);

触发所有 SpringApplicationRunListener 监听器的 running 事件方法。

⑩⑧返回应用上下文

return context;
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值