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

来源:互联网 发布:php system 返回值 编辑:程序博客网 时间:2024/06/05 18:34

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个类)
ApplicationContextInitializer

SpringBoot实例化的9个ApplicationListener(另开一篇写这9个类)
ApplicationListener

三、执行方法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
SpringApplicationRunListener
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刷新上下文
重点后面另开一篇

0 0
原创粉丝点击