SpringBoot启动流程(概括)

Spring boot是Spring家族中的一个全新的框架,它用来简化Spring应用程序的创建和开发过程。

特性

1.自动配置:针对很多Spring应用程序和常见的应用功能,Spring boot能自动提供相关配置;:
2.起步依赖:告诉Spring boot需要什么功能,它就能引入需要的依赖库;
3.Actuator:让你能够深入运行中的Spring Boot应用程序,一探Spring boot程序的内部信息;
4.命令行界面:这是Spring Boot的可选特性,主要针对Groovy语言使用。

启动流程大致分为两步一是对primarySources的准备工作二是运行run步骤

public SpringApplication(Class... primarySources) {
    this((ResourceLoader)null, primarySources);
}

这边主要做了以下4个步骤:

  1. 判断当前应用程序的类型NONE、SERVLET、REACTIVE
  2. 加载所有的初始化容器
  3. 加载所有的监听器
  4. 找到程序运行的主类

方法里面调用的构造方法如下:

public SpringApplication(ResourceLoader resourceLoader, Class... primarySources) {
    this.sources = new LinkedHashSet();
    this.bannerMode = Mode.CONSOLE;
    this.logStartupInfo = true;
    this.addCommandLineProperties = true;
    this.headless = true;
    this.registerShutdownHook = true;
    this.additionalProfiles = new HashSet();
    this.resourceLoader = resourceLoader;
    Assert.notNull(primarySources, "PrimarySources must not be null");
    this.primarySources = new LinkedHashSet(Arrays.asList(primarySources));
    this.webApplicationType = this.deduceWebApplicationType();
    this.setInitializers(this.getSpringFactoriesInstances(ApplicationContextInitializer.class));
    this.setListeners(this.getSpringFactoriesInstances(ApplicationListener.class));
    this.mainApplicationClass = this.deduceMainApplicationClass();
}

接下来就是run方法:

/**
	 * 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) {
        //第一步:开启计时器
        //设置当前任务的id和启动的时间,方便后续的时候
        //进行计时的操作
		StopWatch stopWatch = new StopWatch();
		stopWatch.start();
        //设置空值以及异常集合,不是很重要
		ConfigurableApplicationContext context = null;
		Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList<>();
		
        //第二步:配置系统属性java.awt.headless意义不大,可以忽略
		configureHeadlessProperty();
		
        //第三步:获取一个EventPublishingRunListeners的对象,此对象会贯穿整个应用程序启动的过程,每次在进行监听器操作的时候都会从中获取具体的监听器
        SpringApplicationRunListeners listeners = getRunListeners(args);
		listeners.starting();
		try {
		
            //第四步:加载命令行的参数值,解析在命令行中通过--key=value输入的属性值,封装到ApplicationArguments对象中
			ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
			
            //第五步:准备当前的应用环境
			ConfigurableEnvironment environment = prepareEnvironment(listeners, applicationArguments);
			
            //第六步:设置系统属性,保证某些bean不会添加到准备的环境中spring.beaninfo.ignore
			configureIgnoreBeanInfo(environment);
			
            //第七步:准备banner的打印,就是刚开始运行的图片
			Banner printedBanner = printBanner(environment);
			
            //第八步:准备上下文应用对象,根据当前应用程序的类型来判断创建什么格式的上下文对象
			context = createApplicationContext();
			
             //第九步:设置异常报告器对象
			exceptionReporters = getSpringFactoriesInstances(SpringBootExceptionReporter.class,
					new Class[] { ConfigurableApplicationContext.class }, context);
					
            //第十步:设置异常报告器对象 准备当前上下文对象
            //1.设置初始化进行执行,向beanfactory中注入了三个postprocessor的对象,后续在自动装配的时候会用到applylnitializers(context);
            //2.listeners.contextPrepared(context);
            //3.加载很多资源配置,自动装配在此环节完成load(context,sources.toArray(new Object[]);
            //4.listeners.contextLoaded(context);
			prepareContext(context, environment, listeners, applicationArguments, printedBanner);
			
            //第十一步:刷新上下文环境(关键操作),已经在spring的时候会讲到
			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;
	}

同时附上关于SpringBoot的启动原理图:

spring boot app 启动 spring boot的启动过程_spring boot