首页 > 其他分享 >springboot启动流程

springboot启动流程

时间:2022-12-15 19:11:29浏览次数:77  
标签:springboot 启动 流程 listeners context stopWatch new 加载

主要看下new SpringApplication逻辑和run方法逻辑:

new SpringApplication逻辑:

进入run方法后,会 new 一个SpringApplication 对象,创建这个对象的构造函数做了一些准备工作,核心步骤如下:
1.确定应用程序类型
在SpringApplication的构造方法内,首先会通过 WebApplicationType.deduceFromClasspath(); 方法判断当前应用程序的容器,默认使用的是Servlet 容器,除了servlet之外,还有NONE 和 REACTIVE (响应式编程);
2.加载所有的初始化器
从 META-INF/spring.factories 配置文件中加载实现了ApplicationContextInitializer接口的类
3.加载所有的监听器
从 META-INF/spring.factories 配置文件中加载实现了 ApplicationListener 接口的类
4.设置程序运行的主类,为后面的扫包作准备。

 

run方法逻辑:

 

 public ConfigurableApplicationContext run(String... args) {
	//创建stopWatch,统计run方法执行耗时
        StopWatch stopWatch = new StopWatch();
	//开始启动计时
        stopWatch.start();
        ConfigurableApplicationContext context = null;
        Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList();
        this.configureHeadlessProperty();
	//加载所有SpringApplicationRunListener监听器
        SpringApplicationRunListeners listeners = this.getRunListeners(args);
	//调用SpringApplicationRunListener的starting方法
        listeners.starting();
        Collection exceptionReporters;
        try {
	    //将springApplication的启动参数封装为ApplicationArguments
            ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
	    //创建Springboot应用使用的环境变量,内部会根据webApplicationType创建不同的环境变量
	    //这里会创建StandardServletEnvironment
            ConfigurableEnvironment environment = this.prepareEnvironment(listeners, applicationArguments);
            this.configureIgnoreBeanInfo(environment);
	    //打印banner
            Banner printedBanner = this.printBanner(environment);
	    //根据webApplicationType创建AnnotationConfigServletWebServerApplicationContext对象
            context = this.createApplicationContext();
	    //加载springboot的异常报告对象,当springboot启动抛异常时,会通过该对象打印错误日志
            exceptionReporters = this.getSpringFactoriesInstances(SpringBootExceptionReporter.class, new Class[]{ConfigurableApplicationContext.class}, context);
	   //准备上下文环境
            this.prepareContext(context, environment, listeners, applicationArguments, printedBanner);
	   //调用applicationContext的refresh方法,启动整个spring应用程序,springboot自动装配也是在此流程里面进行的
            this.refreshContext(context);
	    //留给用户拓展
            this.afterRefresh(context, applicationArguments);
	    //结束计时器
            stopWatch.stop();
            if (this.logStartupInfo) {
                (new StartupInfoLogger(this.mainApplicationClass)).logStarted(this.getApplicationLog(), stopWatch);
            }
            //发布上下文准备就绪事件,调用SpringApplicationListener对象的started监听方法
            listeners.started(context);
	    //回调spring中的ApplicationRunner对象和CommandLineRunner 
            this.callRunners(context, applicationArguments);
        } catch (Throwable var10) {
	    //抛出异常,则使用SpringBootExceptionReporter打印异常报告
            this.handleRunFailure(context, var10, exceptionReporters, listeners);
            throw new IllegalStateException(var10);
        }

        try {
	    //启动成功,调用SpringApplicationListener对象的running方法
            listeners.running(context);
            return context;
        } catch (Throwable var9) {
	   //抛出异常,则使用SpringBootExceptionReporter打印异常报告
            this.handleRunFailure(context, var9, exceptionReporters, (SpringApplicationRunListeners)null);
            throw new IllegalStateException(var9);
        }
    }

 

标签:springboot,启动,流程,listeners,context,stopWatch,new,加载
From: https://www.cnblogs.com/lufei-123/p/16985863.html

相关文章