Spring Boot【原理分析】(1)——SpringApplication

SpringApplication作为Spring Boot的启动类。

一、入口方法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);
}

实例SpringApplication执行run。

二、初始化函数initialize

SpringApplication构造方法,会调用initialize方法进行初始化。

@SuppressWarnings({ "unchecked", "rawtypes" })
private void initialize(Object[] sources) {
    if (sources != null && sources.length > 0) {
        this.sources.addAll(Arrays.asList(sources));
    }
    this.webEnvironment = deduceWebEnvironment();
    setInitializers((Collection) getSpringFactoriesInstances(
            ApplicationContextInitializer.class));
    setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));
    this.mainApplicationClass = deduceMainApplicationClass();
}

流程分析:
1.设置配置类
2.推断是否为WEB环境
3.实例化META-INF/spring.factories文件中的ApplicationContextInitializer类
4.实例化META-INF/spring.factories文件中的ApplicationListener类
5.推断主类

SpringBoot实例化的5个ApplicationContextInitializer(另开一篇写这5个类)
《Spring Boot【原理分析】(1)——SpringApplication》

SpringBoot实例化的9个ApplicationListener(另开一篇写这9个类)
《Spring Boot【原理分析】(1)——SpringApplication》

三、执行方法run

源码如下:

public ConfigurableApplicationContext run(String... args) {
    StopWatch stopWatch = new StopWatch();
    stopWatch.start();
    ConfigurableApplicationContext context = null;

    //设置java.awt.headless未配置时默认为true
    //是J2SE的一种Headless模式
    configureHeadlessProperty();
    //实例化SpringApplicationRunListeners
    //<1>实例化META-INF/spring.factories文件中的SpringApplicationRunListener类
    SpringApplicationRunListeners listeners = getRunListeners(args);
    //这里看起来是一个启动,其实根据不同的listener不一样。
    listeners.started();
    try {
        ApplicationArguments applicationArguments = new DefaultApplicationArguments(
                args);
        //<2>创建并刷新spring上下文 
        context = createAndRefreshContext(listeners, applicationArguments);
        afterRefresh(context, applicationArguments);
        // EventPublishingRunListener广播ApplicationReadyEvent或ApplicationFailedEvent事件
        listeners.finished(context, null);
        stopWatch.stop();
        if (this.logStartupInfo) {
            new StartupInfoLogger(this.mainApplicationClass)
                    .logStarted(getApplicationLog(), stopWatch);
        }
        return context;
    }
    catch (Throwable ex) {
        handleRunFailure(context, listeners, ex);
        throw new IllegalStateException(ex);
    }
}

1.启动所有SpringApplicationRunListener
SpringBoot实例化的1个SpringApplicationRunListener
《Spring Boot【原理分析】(1)——SpringApplication》
EventPublishingRunListener会向SpringApplication的所有ApplicationListener广播事件。
事件有:ApplicationStartedEvent;ApplicationEnvironmentPreparedEvent;ApplicationPreparedEvent;ApplicationFailedEvent;ApplicationReadyEvent
源码中listeners.started(); 广播ApplicationStartedEvent事件。

2.创建并刷新spring上下文
源码如下:

private ConfigurableApplicationContext createAndRefreshContext(
        SpringApplicationRunListeners listeners,
        ApplicationArguments applicationArguments) {
    ConfigurableApplicationContext context;
    // Create and configure the environment
    ConfigurableEnvironment environment = getOrCreateEnvironment();
    configureEnvironment(environment, applicationArguments.getSourceArgs());
    //EventPublishingRunListener广播ApplicationEnvironmentPreparedEvent
    listeners.environmentPrepared(environment);
    if (isWebEnvironment(environment) && !this.webEnvironment) {
        environment = convertToStandardEnvironment(environment);
    }

    if (this.bannerMode != Banner.Mode.OFF) {
        printBanner(environment);
    }

    // <2.1>Create, load, refresh and run the ApplicationContext
    context = createApplicationContext();
    context.setEnvironment(environment);
    postProcessApplicationContext(context);
    // 初始化所有ApplicationContextInitializer
    // 载入BeanFactoryPostProcessor
    applyInitializers(context);
    listeners.contextPrepared(context);
    if (this.logStartupInfo) {
        logStartupInfo(context.getParent() == null);
        logStartupProfileInfo(context);
    }

    // Add boot specific singleton beans
    context.getBeanFactory().registerSingleton("springApplicationArguments",
            applicationArguments);

    // Load the sources
    Set<Object> sources = getSources();
    Assert.notEmpty(sources, "Sources must not be empty");
    load(context, sources.toArray(new Object[sources.size()]));
    // 对ApplicationContextAware的ApplicationListener设置context
    // context添加所有ApplicationListener
    // EventPublishingRunListener广播ApplicationPreparedEvent事件
    listeners.contextLoaded(context);

    //<2.2> Refresh the context
    refresh(context);
    if (this.registerShutdownHook) {
        try {
            context.registerShutdownHook();
        }
        catch (AccessControlException ex) {
            // Not allowed in some environments.
        }
    }
    return context;
}

2.1创建context
根据不同的environment会创建不同的ApplicationContext。
Web:AnnotationConfigEmbeddedWebApplicationContext
Standard:AnnotationConfigApplicationContext

2.2刷新上下文
重点后面另开一篇

    原文作者:Spring Boot
    原文地址: https://blog.csdn.net/wwmfeng/article/details/53463292
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞