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)


相关推荐

  • ArcGIS必会的几个工具的应用 –提取、分割、融合、裁剪(矢)、合并、追加、镶嵌、裁剪(栅)、重采样

    ArcGIS必会的几个工具的应用 –提取、分割、融合、裁剪(矢)、合并、追加、镶嵌、裁剪(栅)、重采样ArcGIS必会的几个工具的应用–提取、分割、融合、裁剪(矢)、合并、追加、镶嵌、裁剪(栅)、重采样GIS思维今天我们来聊聊ArcGIS中常用你又必须掌握的几个工具,如筛选、分割、融合、裁剪(矢量)、合并、追加、镶嵌、裁剪…

  • 校准不好TOF相机就废了?

    校准不好TOF相机就废了?校准不好TOF相机就废了?原文:(143条消息)校准不好TOF相机就废了?_深度视觉小司机的博客-CSDN博客五种校准一、镜头校准二、温度校准三、非线性校准四、共偏校准五、逐像素校准六、结语校准不好TOF相机就废了?目前,手机相机的进化方向是多摄中加入3D技术,而3D技术的一个很重要的路线是TOF,各大手机厂商都有对应的机型。关于TOF相机的原理,之前已经有很多科普文章了,今天我们就来聊一聊对TOF相机很重要的校准标定。五种校准TOF相机可以产生距离信息即深度信息,而深度.

  • 作业总结:磨皮滤镜(双边滤波bilateralFilter)代码实现[通俗易懂]

    作业总结:磨皮滤镜(双边滤波bilateralFilter)代码实现[通俗易懂]双边滤波是一种非线性的滤波方法,是结合图像的空间邻近度和像素值相似度的一种折衷处理,同时考虑空间与信息和灰度相似性,达到保边去噪的目的,具有简单、非迭代、局部处理的特点。之所以能够达到保边去噪的滤波效果是因为滤波器由两个函数构成:一个函数是由几何空间距离决定滤波器系数,另一个是由像素差值决定滤波器系数.1Python:cv2.bilateralFilter(src,d,sigm…

  • 登录的时候出现token无效_token已过期

    登录的时候出现token无效_token已过期msg:‘无效token’,status:400原因:用第三方组件element-ui或者其他组件的单个功能上传图片,没有用到axios发请求,而是组件内部自己封装了一个ajax去发请求,组件内部封装的ajax不携带Authorization字段.解决方案:1.首先在上传组件中手动添加:headers:”headerObj”2.再设置上传组件的请求头,添加Authorization字段:就解决了。…

  • hanoi塔问题如下图所示_hanoi塔问题最经典的算法

    hanoi塔问题如下图所示_hanoi塔问题最经典的算法什么是hanoi塔?汉诺塔问题:古代有一个梵塔,塔内有三个座A、B、C,A座上有64个盘子,盘子大小不等,大的在下,小的在上。有一个和尚想把这64个盘子从A座移到B座,但每次只能允许移动一个盘子,并且在移动过程中,3个座上的盘子始终保持大盘在下,小盘在上。如下图问题解答问题定义我们把左边的柱子叫做A,中间的柱子叫做B,右边的柱子叫做Chanoi塔的搬运过程;i

    2022年10月25日

发表回复

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

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