SpringBoot面试篇(1)

一.启动流程:(源码深度解析)

  ,

Springboot启动流程就是这两个核心方法,一个是new SpringApplication()构造方法,一个是上面的run()方法。

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;

    // 检查 primarySources 参数是否为空,如果为空则抛出异常
    Assert.notNull(primarySources, "PrimarySources must not be null");
    // 将主要来源(primarySources)添加到一个 LinkedHashSet 集合中
    this.primarySources = new LinkedHashSet(Arrays.asList(primarySources));

    // 推断 web 应用程序类型(Servlet、Reactive 或无 Web 环境)
    this.webApplicationType = WebApplicationType.deduceFromClasspath();

    // 获取并初始化 BootstrapRegistryInitializer
    this.bootstrapRegistryInitializers = new ArrayList(this.getSpringFactoriesInstances(BootstrapRegistryInitializer.class));

    // 获取并设置 ApplicationContextInitializer
    this.setInitializers(this.getSpringFactoriesInstances(ApplicationContextInitializer.class));

    // 获取并设置 ApplicationListener
    this.setListeners(this.getSpringFactoriesInstances(ApplicationListener.class));

    // 推断应用程序的主类
    this.mainApplicationClass = this.deduceMainApplicationClass();
}
​

主要有一下几个主要的步骤:

1.确认web应用类型

2.加载ApplicationInitializer

3.记载ApplicationLinstener

4.记录主启动类

2.run()方法

首先看源码:

public ConfigurableApplicationContext run(String... args) {
    // 获取程序启动时间
    long startTime = System.nanoTime();
    
    // 创建 BootstrapContext 对象
    DefaultBootstrapContext bootstrapContext = this.createBootstrapContext();
    
    // 配置 Headless 属性
    this.configureHeadlessProperty();
    
    // 获取 SpringApplicationRunListeners 对象并执行 starting 方法,记录监听器
    SpringApplicationRunListeners listeners = this.getRunListeners(args);
    listeners.starting(bootstrapContext, this.mainApplicationClass);

    try {
        // 创建 ApplicationArguments 对象并准备环境
        ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
        ConfigurableEnvironment environment = this.prepareEnvironment(listeners, bootstrapContext, applicationArguments);
        
        // 打印 Banner
        Banner printedBanner = this.printBanner(environment);
        
        // 创建 ApplicationContext,声明一个容器变量context
        ConfigurableApplicationContext context = this.createApplicationContext();
        context.setApplicationStartup(this.applicationStartup);
        
        // 准备上下文,包括设置环境、初始化器、监听器等
        this.prepareContext(bootstrapContext, context, environment, listeners, applicationArguments, printedBanner);
        
        // 刷新 ApplicationContext
        this.refreshContext(context);
        
        // 在刷新后执行其他操作
        this.afterRefresh(context, applicationArguments);
        
        // 计算启动时间
        Duration timeTakenToStartup = Duration.ofNanos(System.nanoTime() - startTime);
        
        // 如果 logStartupInfo 为 true,则记录启动信息日志
        if (this.logStartupInfo) {
            (new StartupInfoLogger(this.mainApplicationClass)).logStarted(this.getApplicationLog(), timeTakenToStartup);
        }
        
        // 执行 started 方法
        listeners.started(context, timeTakenToStartup);
        
        // 调用运行器
        this.callRunners(context, applicationArguments);
    } catch (Throwable var12) {
        // 处理运行失败的情况
        if (var12 instanceof AbandonedRunException) {
            throw var12;
        }
        this.handleRunFailure(context, var12, listeners);
        throw new IllegalStateException(var12);
    }

    try {
        // 如果 ApplicationContext 运行中,则执行 ready 方法
        if (context.isRunning()) {
            Duration timeTakenToReady = Duration.ofNanos(System.nanoTime() - startTime);
            listeners.ready(context, timeTakenToReady);
        }

        return context;
    } catch (Throwable var11) {
        // 处理运行失败的情况
        if (var11 instanceof AbandonedRunException) {
            throw var11;
        } else {
            this.handleRunFailure(context, var11, (SpringApplicationRunListeners)null);
            throw new IllegalStateException(var11);
        }
    }
}

总的来说,主要有如下几个主要的步骤:

1.准备环境对象,Environment,用于加载对象属性,

2.打印Banner

3.实例化一个容器Context

4.接下来准备容器,为容器设置Environment,BeanFactory,

5.刷新容器

6.最后返回

3.情景再现

HR:说一下Springboot的启动流程?

你:

Spring boot启动,其本质就是加载各种的配置信息,然后初始化容器并返回。

在启动的过程中主要有一下步骤,

首先,当我们在启动类里面执行SpringApplication.run()这行代码时候,在方法内部会做两个事情,      1.创建SpringApplication对象,

    2.执行run()方法

其次在创建对象的时候,在构造方法的内部主要有3个步骤:

   1.确认web的应用类型,是servlet或者是无web类型,如果是前者,会自动启动一个tomcat

   2.在spring.factories中,加载默认的ApplicationInitializer和ApplicationListener等

   3.记录当前应用的启动类

最后当对象创建好了之后会调用run()方法,而在run()方法中主要执行以下步骤:

   1.准备Environment环境对象,它封装了一些当前应用运行的环境参数,比如环境变量,

   2.实例化容器,这个步骤仅仅是创建ApplicationContext容器

   3.创建好容器之后会为容器做准备工作,比如加载BeanFactoryPostProcessor后置处理器,并加        载主类对应的Definition

   4.刷新容器,此时真正创建Bean实例

总结:

其实核心就两步骤,一个是创建Spring Application对象以及run方法的调用,在run方法中会实例化容器,并且创建需要的Bean实例

  • 15
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值