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

 2019-10-17 21:47  阅读(1035)
文章分类:Spring boot

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个类)
20191017100155\_1.png

SpringBoot实例化的9个ApplicationListener(另开一篇写这9个类)
20191017100155\_2.png

三、执行方法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
20191017100155\_3.png
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)
版权归原创作者所有,任何形式转载请联系作者; Java 技术驿站 >> Spring Boot【原理分析】(1)——SpringApplication

相关推荐