简单清晰的SpringBoot启动流程


前言

SpringBoot启动流程总体分为两步,第一步先SpringApplication对象,第二步为执行run()方法。我们只要抓住这个思路,在深入研究每一步背后做了什么,对SpringBoot的启动流程就能熟练掌握。


一、创建SpringApplication对象

1.首先进入run()方法,run方法中new创建了一个SpringApplication实例。
在这里插入图片描述

在这里插入图片描述
2.下面是创建SpringApplication实例所做的一系列操作。
在这里插入图片描述

总结:SpringApplication实例所做的一系列操作有以下几个关键步骤:

  1. SpringApplication对象在初始化时,从类路径中推断并设置应用类型。应用类型有三种:非web应用,基于servlet的web应用和基于REACTIVE的web应用。
  2. 从SpringFactories文件中找到配置的事件监听器,并保存起来
  3. 推断运行主类

二、执行 run() 方法

创建完SpringApplication实例之后,继续执行run方法,run方法的源码如下。

	public ConfigurableApplicationContext run(String... args) {
	    //1.开启程序启动计时器
		long startTime = System.nanoTime();
		DefaultBootstrapContext bootstrapContext = createBootstrapContext();
		ConfigurableApplicationContext context = null;
		//2.无输入不影响工作
		configureHeadlessProperty();
		//3.获取监听器
		SpringApplicationRunListeners listeners = getRunListeners(args);
		//4.启动监听器
		listeners.starting(bootstrapContext, this.mainApplicationClass);
		try {
		    //5.设置程序启动参数
			ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
			//6.配置环境
			ConfigurableEnvironment environment = prepareEnvironment(listeners, bootstrapContext, applicationArguments);
			//7.跳过bean检索
			configureIgnoreBeanInfo(environment);
			//8.打印banner
			Banner printedBanner = printBanner(environment);
			//9.创建应用程序上下文
			context = createApplicationContext();
			context.setApplicationStartup(this.applicationStartup);
			prepareContext(bootstrapContext, context, environment, listeners, applicationArguments, printedBanner);
			//10.刷新上下文
			refreshContext(context);
			//11.上下文后置处理
			afterRefresh(context, applicationArguments);
			//12.结束计时器
			Duration timeTakenToStartup = Duration.ofNanos(System.nanoTime() - startTime);
			if (this.logStartupInfo) {
				new StartupInfoLogger(this.mainApplicationClass).logStarted(getApplicationLog(), timeTakenToStartup);
			}
			//13.启动监听器
			listeners.started(context, timeTakenToStartup);
			//14.通知程序运行
			callRunners(context, applicationArguments);
		}
		catch (Throwable ex) {
			handleRunFailure(context, ex, listeners);
			throw new IllegalStateException(ex);
		}
		try {
			Duration timeTakenToReady = Duration.ofNanos(System.nanoTime() - startTime);
			listeners.ready(context, timeTakenToReady);
		}
		catch (Throwable ex) {
			handleRunFailure(context, ex, null);
			throw new IllegalStateException(ex);
		}
		return context;
	}

该方法中实现了如下几个关键步骤:

  1. 创建了应用的监听器SpringApplicationRunListeners并开始监听。
  2. 加载SpringBoot配置环境(ConfigurableEnvironment),如果是通过web容器发布,会加载StandardEnvironment,其最终也是继承了ConfigurableEnvironment。
  3. 创建run方法的返回对象:ConfigurableApplicationContext(应用配置上下文)。ConfigurableApplicationContext是ApplicationContext的子类,该接口的主要任务就是配置应用上下文功能。
  4. 回到run方法内,prepareContext方法将listeners、environment、applicationArguments、banner等重要组件与上下文对象关联。
  5. 接下来的refreshContext(context)方法是实现spring-boot-starter-*(mybatis、redis等)自动化配置的关键,包括spring.factories的加载,bean的实例化等核心工作。
  6. 启动监听器,通知程序运行

总结:Springboot的启动,主要创建了配置环境(environment)、事件监听(listeners)、应用上下文(applicationContext),并基于以上条件,在容器中开始实例化我们需要的Bean。


总结

SpringApplication类为我们引导项目提供了一种便利的方式——通过main()方法直接启动。大多数情况下,我们可以把项目启动这个任务直接委托给SpringApplication.run方法。所以我们在学习SpringBoot启动流程时,抓住两点即可:1.创建并初始化SpringApplication ;2.执行run()方法。


  • 6
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

JinziH Never Give Up

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值