码迷,mamicode.com
首页 > 编程语言 > 详细

spring boot 源码解析 启动流程

时间:2019-07-08 13:46:01      阅读:133      评论:0      收藏:0      [点我收藏+]

标签:ati   UNC   types   port   strong   string   rgs   event   app   

spring boot 源码解析 启动流程

在面试过程中经常被问到过spring boot的启动流程,今天就翻一下源码整体看一下;

首先,新建一个启动类,可以看到是首先调用的SpringApplication的静态方法run

@SpringBootApplication
public class SourceReadApplillcation {

    public static void main(String[] args) {
        SpringApplication.run(SourceReadApplillcation.class,args);
    }
}
  1. 这里传入启动类的class,然后调用SpringApplication的构造函数new一个实例,接着调用run方法;
public static ConfigurableApplicationContext run(Class<?> primarySource,
            String... args) {
        return run(new Class<?>[] { primarySource }, args);
}
public static ConfigurableApplicationContext run(Class<?>[] primarySources,
            String[] args) {
        return new SpringApplication(primarySources).run(args);
}
public SpringApplication(Class<?>... primarySources) {
        this(null, primarySources);
}

    
@SuppressWarnings({ "unchecked", "rawtypes" })
public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) {
    this.resourceLoader = resourceLoader;
    
    Assert.notNull(primarySources, "PrimarySources must not be null");
    this.primarySources = new LinkedHashSet<>(Arrays.asList(primarySources));
    //推断web应用类型;
    this.webApplicationType = WebApplicationType.deduceFromClasspath();
    //设置初始化器,从META-INF/spring.factories读取ApplicationContextInitializer
    //配置的值,读取详情后续研究
    setInitializers((Collection) getSpringFactoriesInstances(
            ApplicationContextInitializer.class));
    //设置监听器,同上,读取ApplicationListener配置的值
    setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));
    //设置应用main启动类
    this.mainApplicationClass = deduceMainApplicationClass();
}

负责启动SpringBoot的主要方法

public ConfigurableApplicationContext run(String... args) {
    //计时器,主要为了统计消耗时间
    StopWatch stopWatch = new StopWatch();
    stopWatch.start();
    
    //初始化应用上下文和异常报告集合
    ConfigurableApplicationContext context = null;
    Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList<>();
    
    //设置java.awt.headless模式为true
    onfigureHeadlessProperty();
    
    //设置并启动META-INF/spring.factories下SpringApplicationRunListener配置的监听器
    //这里为EventPublishingRunListener,会通过反射调用其构造函数进行初始化
    //并将一开始设置的监听器保存到AbstractApplicationEventMulticaster的
    //内部类ListenerRetriever中,详情后续
    SpringApplicationRunListeners listeners = getRunListeners(args);
    //出发监听器开始启动事件
    listeners.starting();
    try {
        //初始化应用参数,例如启动设置的命令行参数等,可以通过这个类获取
        ApplicationArguments applicationArguments = new DefaultApplicationArguments(
                args);
        //准备运行环境
        ConfigurableEnvironment environment = prepareEnvironment(listeners,
                applicationArguments);
        configureIgnoreBeanInfo(environment);
        //打印banner
        Banner printedBanner = printBanner(environment);
        //创建上下文,Springboot他默认为AnnotationConfigApplicationContext
        context = createApplicationContext();
        //准备异常报告
        exceptionReporters = getSpringFactoriesInstances(
                SpringBootExceptionReporter.class,
                new Class[] { ConfigurableApplicationContext.class }, context);
        //准备上下文
        prepareContext(context, environment, listeners, applicationArguments,
                printedBanner);
        //刷新上下文
        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;
}

整个启动流程大体就是这样,先有一个整体的概念,其中实现细节很庞杂,后续逐一研究

spring boot 源码解析 启动流程

标签:ati   UNC   types   port   strong   string   rgs   event   app   

原文地址:https://www.cnblogs.com/NealRiver/p/11150367.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!