【Spring-Boot】源码 简解析 之 启动流程

断点源码

只分析主要方法
源码版本:1.5.10

package com.example.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class DemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }
}

@SpringBootApplication包含以下三个注解
// 使用JavaConfig形式,不用xml
@SpringBootConfiguration
// 开启自动配置
@EnableAutoConfiguration
// 自动包扫描
@ComponentScan
1. initialize方法
private void initialize(Object[] sources) {

        // 1.初始化成员变量sources
        if (sources != null && sources.length > 0) {
            this.sources.addAll(Arrays.asList(sources));
        }
        
        // 2.初始化成员变量webEnvironment,判断应用类型
        // javax.servlet.Servlet 或者 org.springframework.web.context.ConfigurableWebApplicationContext
        this.webEnvironment = deduceWebEnvironment();
        
        // 3.初始化成员变量initializers
        // spring.factories文件中key为ApplicationContextInitializer的类实例化
        // 设置到SpringApplication的initializers属性中,找出所有的应用程序初始化器
        setInitializers((Collection) getSpringFactoriesInstances(
                ApplicationContextInitializer.class));

        // 4.初始化成员变量listeners
        // spring.factories文件中key为ApplicationListener的类实例化
        // 设置到SpringApplication的listeners属性中,找出所有的应用程序事件监听器 
        setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));
        
        // 5.初始化成员变量mainApplicationClass,找应用的入口类
        this.mainApplicationClass = deduceMainApplicationClass();
    }
2. run方法
public ConfigurableApplicationContext run(String... args) {

        // 1.开始记录时间
        StopWatch stopWatch = new StopWatch();
        stopWatch.start();
        ConfigurableApplicationContext context = null;
        FailureAnalyzers analyzers = null;

        // 2.设置java.awt.headless系统属性为true
        configureHeadlessProperty();
        
        // 3.获取SpringApplicationRunListeners,内部只有一个EventPublishingRunListener
        SpringApplicationRunListeners listeners = getRunListeners(args);
        
        // 4.接受ApplicationStartedEvent事件的listener会执行相应的操作
        listeners.starting();
        try {
            
            // 5.构造一个应用程序参数持有类
            ApplicationArguments applicationArguments = new DefaultApplicationArguments(
                    args);
            
            // 6.根据SpringApplicationRunListeners以及参数来准备环境 
            ConfigurableEnvironment environment = prepareEnvironment(listeners,
                    applicationArguments);

            // 7.打印logo
            Banner printedBanner = printBanner(environment);
            
            // 8.创建Spring容器
            context = createApplicationContext();
            
            // 9.创建异常分析器 
            analyzers = new FailureAnalyzers(context);

            // 10.Spring上下文前置处理
            prepareContext(context, environment, listeners, applicationArguments,
                    printedBanner);
            
            // 11.Spring上下文刷新
            refreshContext(context);

            // 12.容器创建完成之后执行额外一些操作
            afterRefresh(context, applicationArguments);
            
            // 13.广播出ApplicationReadyEvent事件给相应的监听器执行
            listeners.finished(context, null);

            // 14.停止计时
            stopWatch.stop();
            if (this.logStartupInfo) {
                new StartupInfoLogger(this.mainApplicationClass)
                        .logStarted(getApplicationLog(), stopWatch);
            }
            return context;
        }
        catch (Throwable ex) {
            handleRunFailure(context, listeners, analyzers, ex);
            throw new IllegalStateException(ex);
        }
    }
3. run方法中的prepareContext方法
private void prepareContext(ConfigurableApplicationContext context,
            ConfigurableEnvironment environment, SpringApplicationRunListeners listeners,
            ApplicationArguments applicationArguments, Banner printedBanner) {

        // 1.把环境和上下文关联起来
        context.setEnvironment(environment);

        // 2.为上下文配置Bean生成器以及资源加载器
        postProcessApplicationContext(context);

        // 3.调用初始化器
        applyInitializers(context);

        // 4.触发Spring Boot启动过程的contextPrepared事件
        listeners.contextPrepared(context);
        if (this.logStartupInfo) {
            logStartupInfo(context.getParent() == null);
            logStartupProfileInfo(context);
        }

        // Add boot specific singleton beans
        // 5.添加两个Spring Boot中的特殊单例Bean:springApplicationArguments和springBootBanner
        context.getBeanFactory().registerSingleton("springApplicationArguments",
                applicationArguments);
        if (printedBanner != null) {
            context.getBeanFactory().registerSingleton("springBootBanner", printedBanner);
        }

        // Load the sources
        // 6.加载sources:对于DemoApplication而言,这里的sources集合只包含了它一个class对象
        Set<Object> sources = getSources();
        Assert.notEmpty(sources, "Sources must not be empty");
        
        // 7.加载动作:构造BeanDefinitionLoader并完成Bean定义的加载
        load(context, sources.toArray(new Object[sources.size()]));
        
        // 8.触发Spring Boot启动过程的contextLoaded事件
        listeners.contextLoaded(context);
    }
    原文作者:Spring Boot
    原文地址: https://blog.csdn.net/Q1013331Q/article/details/80198546
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞