springboot启动类–SpringApplication.run()详解

springboot启动类–SpringApplication.run()详解前言实习的第一个项目是利用springboot完成一个需求,在项目搭建的过程中真正感受到springboot的强大,springboot的起步依赖以及自动配置特性简直不要太爽,在项目搭建的过程中解放了我们的小手。而springboot的启动也非常简单,只需要启动springboot的启动类,springboot会帮助我们准备所有的环境,包括server,监听器,装配spring的上下文等等,s…

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺

前言

实习的第一个项目是利用springboot完成一个需求,在项目搭建的过程中真正感受到springboot的强大,springboot的起步依赖以及自动配置特性简直不要太爽,在项目搭建的过程中解放了我们的小手。而springboot的启动也非常简单,只需要启动springboot的启动类,springboot会帮助我们准备所有的环境,包括server,监听器,装配spring的上下文等等,springboot的启动类如此强大我们没有理由不去深究一下。

目录

启动类

创建SpringApplication对象

调用run方法

总结


启动类

@SpringBootApplication
public class SpringTestApplication {

	public static void main(String[] args) {
		SpringApplication.run(SpringTestApplication.class, args);
	}

}

SpringTestApplication类执行main方法,main方法调用SpringApplication的run方法。

run方法干了两件事:

  1. 创建SpringApplication对象
  2. 利用创建好的SpringApplication对象调用run方法

创建SpringApplication对象

在执行SpringApplication的run方法时首先会创建一个SpringApplication类的对象,利用构造方法创建SpringApplication对象时会调用initialize方法。

SpringApplication.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);
	}

public SpringApplication(Object... sources) {
		initialize(sources);
	}

initialize方法:

private void initialize(Object[] sources) {
    // 在sources不为空时,保存配置类
    if (sources != null && sources.length > 0) {
        this.sources.addAll(Arrays.asList(sources));
    }
    // 判断是否为web应用
    this.webEnvironment = deduceWebEnvironment();
    // 获取并保存容器初始化类,通常在web应用容器初始化使用
    // 利用loadFactoryNames方法从路径MEAT-INF/spring.factories中找到所有的ApplicationContextInitializer
    setInitializers((Collection) getSpringFactoriesInstances(
        ApplicationContextInitializer.class));
    // 获取并保存监听器
    // 利用loadFactoryNames方法从路径MEAT-INF/spring.factories中找到所有的ApplicationListener
    setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));
    // 从堆栈信息获取包含main方法的主配置类
    this.mainApplicationClass = deduceMainApplicationClass();
}

调用run方法

public ConfigurableApplicationContext run(String... args) {
    StopWatch stopWatch = new StopWatch();
    stopWatch.start();
    ConfigurableApplicationContext context = null;
    FailureAnalyzers analyzers = null;
    // 配置属性
    configureHeadlessProperty();
    // 获取监听器
    // 利用loadFactoryNames方法从路径MEAT-INF/spring.factories中找到所有的SpringApplicationRunListener
    SpringApplicationRunListeners listeners = getRunListeners(args);
    // 启动监听
    // 调用每个SpringApplicationRunListener的starting方法
    listeners.starting();
    try {
        // 将参数封装到ApplicationArguments对象中
        ApplicationArguments applicationArguments = new DefaultApplicationArguments(
            args);
        // 准备环境
        // 触发监听事件——调用每个SpringApplicationRunListener的environmentPrepared方法
        ConfigurableEnvironment environment = prepareEnvironment(listeners,
            applicationArguments);
        // 从环境中取出Banner并打印
        Banner printedBanner = printBanner(environment);
        // 依据是否为web环境创建web容器或者普通的IOC容器
        context = createApplicationContext();
        analyzers = new FailureAnalyzers(context);
        // 准备上下文
        // 1.将environment保存到容器中
        // 2.触发监听事件——调用每个SpringApplicationRunListeners的contextPrepared方法
        // 3.调用ConfigurableListableBeanFactory的registerSingleton方法向容器中注入applicationArguments与printedBanner
        // 4.触发监听事件——调用每个SpringApplicationRunListeners的contextLoaded方法
        prepareContext(context, environment, listeners, applicationArguments,
            printedBanner);
        // 刷新容器,完成组件的扫描,创建,加载等
        refreshContext(context);
        afterRefresh(context, applicationArguments);
        // 触发监听事件——调用每个SpringApplicationRunListener的finished方法
        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);
    }
}

总结

SpringApplication.run一共做了两件事

  1. 创建SpringApplication对象;在对象初始化时保存事件监听器,容器初始化类以及判断是否为web应用,保存包含main方法的主配置类。
  2. 调用run方法;准备spring的上下文,完成容器的初始化,创建,加载等。会在不同的时机触发监听器的不同事件。

参考文献:

【1】.https://www.cnblogs.com/davidwang456/p/5846513.html

【2】.https://mp.weixin.qq.com/s/O2zS2yyLy1Vu_aPtR28wiQ

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/197434.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • Android最常用的控件ListView(详解)

    Android最常用的控件ListView(详解)一.ListView简介在Android开发中,ListView是一个比较常用的控件。它以列表的形式展示具体数据内容,并且能够根据数据的长度自适应屏幕显示。二.ListView简单用法代码部分1.布局界面activity_main.xml代码:<?xmlversion=”1.0″encoding=”utf-8″?><LinearLayoutxmlns:android=”http://schemas.android.com/ap…

  • 电商网站测试要点_电商项目测试点

    电商网站测试要点_电商项目测试点电商网站测试总结:总体按照两种模式进行划分总结:1.按照测试类型2.按照电子商务网站的系统架构 1.按照测试类型来划分 1.兼容性  1.1主要是在浏览器兼容(360浏览器IE6IE8浏览器)  1.2.操作系统,主要体现在操作系统兼容(xpwin2003win2007) 2.UI测试 2.1检查连接是否正确 2.2是否有文字错误信息 2.3产品…

  • OpenGrok在线代码浏览环境搭建

    OpenGrok在线代码浏览环境搭建OpenGrok是专门的源码阅读工具在针对特大型源码时,比如AOSP和Chromium,就需要祭出专门的源码阅读工具。OpenGrok属于另一类,免费,开源,运行流畅,功能也毫不逊色,该工具环境搭建和使用感觉很简单,但最近搭建的过程中遇到各种问题,直到怀疑人生,经历各种磨难最后终于可以到流程使用的程度,特此记录一方面为自己备忘,另一方面希望可以给需要搭建环境的人一些帮助,快速完成,避免重…

  • 链表的基本操作_简单链表

    链表的基本操作_简单链表链表的基本操作这里写目录标题链表的基本操作一:单链表的基础知识二:单链表的建立头插法尾插法三:单链表的遍历四:单链表结点数目判断五:单链表的插入链表头插入任意结点插入链表尾部插入六:单链表的删除七:单链表的查询一:单链表的基础知识为什么需要链表?我们在使用数组存放数据是非常方便,但是由于数组的长度是固定的,所以当存储不同的元素数量时,就很容易出现问题。如果向数组中添加的数量大于数组大小时候,信息无法完全被保存。所以我们需要另一种存储方式来存储数据,其中存储的元素的个数不受限制。这种存储方式就是链

    2022年10月30日
  • anycast隧道_一种以anycast方式部署的CDN监控可用性的方法与流程

    anycast隧道_一种以anycast方式部署的CDN监控可用性的方法与流程本发明涉及一种CDN节点监控可用性的方法,具体涉及一种以anycast方式部署的CDN监控可用性的方法。背景技术:现有CDN可用性的检测方法,一般通过一些探测点检测目的CDN的可用性,在探测到失败时,认为目的CDN不可用;对于以anycast方式部署的CDN监控,得到的结果是不准确的;因为多个探测点发出的探测数据不一定到达了所有的目的CDN;导致探测数据未到达的CDN实际上没有被监控到。技术实现要…

  • 吞食鱼2(FeedingFrenzyTwo) 修改器[通俗易懂]

    吞食鱼2(FeedingFrenzyTwo) 修改器[通俗易懂]童年回忆系列。小时候特别喜欢玩这类游戏,软件不大,很慢的网速也不会下载太久,然后对配置要求不高,很破的电脑也可以玩得很开心。不过也有糟心的时候啊,大鱼太多,无数次死于挑战咬梭子鱼的尾巴……今年最后一天

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号