spring boot 启动流程源码阅读解析

spring boot 启动流程源码阅读解析

  1. 创建SpringApplication对象
  2. 调用SpringApplication run 实现启动同时返回当前的容器上下文
  3. 创建SpringApplication对象实现SpringBoot初始化操作
@SpringBootApplication
public class HzDemoApplication {
    public static void main(String[] args) {
        SpringApplication.run(HzDemoApplication.class, args);
    }
}
  1. 在SpringApplication构造函数中获取当前应用的启动类型
public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) {
        this.sources = new LinkedHashSet();
        this.bannerMode = Mode.CONSOLE;
        this.logStartupInfo = true;
        this.addCommandLineProperties = true;
        this.addConversionService = true;
        this.headless = true;
        this.registerShutdownHook = true;
        this.additionalProfiles = Collections.emptySet();
        this.isCustomEnvironment = false;
        this.lazyInitialization = false;
        this.applicationContextFactory = ApplicationContextFactory.DEFAULT;
        this.applicationStartup = ApplicationStartup.DEFAULT;
        this.resourceLoader = resourceLoader;
        Assert.notNull(primarySources, "PrimarySources must not be null");
        this.primarySources = new LinkedHashSet(Arrays.asList(primarySources));
        //判断当前classpath是否有加载我们的servlet类 返回servlet web启动方式
        this.webApplicationType = WebApplicationType.deduceFromClasspath();
        this.bootstrapRegistryInitializers = new ArrayList(this.getSpringFactoriesInstances(BootstrapRegistryInitializer.class));
        this.setInitializers(this.getSpringFactoriesInstances(ApplicationContextInitializer.class));
        this.setListeners(this.getSpringFactoriesInstances(ApplicationListener.class));
        this.mainApplicationClass = this.deduceMainApplicationClass();
    }
  1. setInitializers 读取SpringBoot包下面的META-INF/spring.factories 获取到对应ApplicationContextInitializer 的实现类装配到集合(initializers)中
this.setInitializers(this.getSpringFactoriesInstances(ApplicationContextInitializer.class));      
  1. setListeners 读取SpringBoot包下面的META-INF/spring.factories 获取到对应ApplicationListener 的实现类装配到集合(listeners)中
this.setListeners(this.getSpringFactoriesInstances(ApplicationListener.class));
  1. mainApplicationClass 获取当前运行的主函数
this.mainApplicationClass = this.deduceMainApplicationClass();
  1. 调用SpringApplication run方法实现启动
public ConfigurableApplicationContext run(String... args) {
        long startTime = System.nanoTime();
        DefaultBootstrapContext bootstrapContext = this.createBootstrapContext();
        ConfigurableApplicationContext context = null;
        this.configureHeadlessProperty();
        SpringApplicationRunListeners listeners = this.getRunListeners(args);
        listeners.starting(bootstrapContext, this.mainApplicationClass);

        try {
            ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
            ConfigurableEnvironment environment = this.prepareEnvironment(listeners, bootstrapContext, applicationArguments);
            this.configureIgnoreBeanInfo(environment);
            Banner printedBanner = this.printBanner(environment);
            context = this.createApplicationContext();
            context.setApplicationStartup(this.applicationStartup);
            this.prepareContext(bootstrapContext, context, environment, listeners, applicationArguments, printedBanner);
            this.refreshContext(context);
            this.afterRefresh(context, applicationArguments);
            Duration timeTakenToStartup = Duration.ofNanos(System.nanoTime() - startTime);
            if (this.logStartupInfo) {
                (new StartupInfoLogger(this.mainApplicationClass)).logStarted(this.getApplicationLog(), timeTakenToStartup);
            }

            listeners.started(context, timeTakenToStartup);
            this.callRunners(context, applicationArguments);
        } catch (Throwable var12) {
            this.handleRunFailure(context, var12, listeners);
            throw new IllegalStateException(var12);
        }

        try {
            Duration timeTakenToReady = Duration.ofNanos(System.nanoTime() - startTime);
            listeners.ready(context, timeTakenToReady);
            return context;
        } catch (Throwable var11) {
            this.handleRunFailure(context, var11, (SpringApplicationRunListeners)null);
            throw new IllegalStateException(var11);
        }
    }
  1. long startTime = System.nanoTime(); 记录启动时间
  2. getRunListeners(args);读取我们的ETA-INF/spring.factories SpringApplicationRunListeners 类型存入到集合中
  private SpringApplicationRunListeners getRunListeners(String[] args) {
        Class<?>[] types = new Class[]{SpringApplication.class, String[].class};
        return new SpringApplicationRunListeners(logger, this.getSpringFactoriesInstances(SpringApplicationRunListener.class, types, this, args), this.applicationStartup);
    }
  1. listeners.starting(bootstrapContext, this.mainApplicationClass);循环调用监听starting方法
  2. .ConfigurableEnvironment environment = this.prepareEnvironment(listeners, bootstrapContext, applicationArguments);利用 listeners 读取我们配置文件数据到SpringBoot容器中
  3. Banner printedBanner = this.printBanner(environment);
  4. context = this.createApplicationContext();创建SpringBoot对应上下文的环境
  5. this.refreshContext(context);刷新上下文
  6. this.onRefresh();开始创建我们的tomcat容器
public void refresh() throws BeansException, IllegalStateException {
        synchronized(this.startupShutdownMonitor) {
            StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh");
            this.prepareRefresh();
            ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();
            this.prepareBeanFactory(beanFactory);

            try {
                this.postProcessBeanFactory(beanFactory);
                StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process");
                this.invokeBeanFactoryPostProcessors(beanFactory);
                this.registerBeanPostProcessors(beanFactory);
                beanPostProcess.end();
                this.initMessageSource();
                this.initApplicationEventMulticaster();
                this.onRefresh();
                this.registerListeners();
                this.finishBeanFactoryInitialization(beanFactory);
                this.finishRefresh();
            } catch (BeansException var10) {
                if (this.logger.isWarnEnabled()) {
                    this.logger.warn("Exception encountered during context initialization - cancelling refresh attempt: " + var10);
                }

                this.destroyBeans();
                this.cancelRefresh(var10);
                throw var10;
            } finally {
                this.resetCommonCaches();
                contextRefresh.end();
            }

        }
    }
  1. 开始加载SpringMVC
    获取spring-boot-configurations下面的META-INF/ spring.factorie所有的类注册到IOC容器中。
    org.springframework.boot.autoconfigure.web.servlet.DispatcherServletAutoConfiguration,
    org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration
  2. this.afterRefresh(context, applicationArguments);定义一个空的模版给其他子类实现重写
  3. listeners.started(context, timeTakenToStartup);使用广播和回调机制通知监听器已SpringBoot容器启动成功
  • 23
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值