欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

SpringBoot 之啟動(dòng)流程詳解

 更新時(shí)間:2023年04月24日 09:08:04   作者:這堆干貨有點(diǎn)猛  
SpringBoot 是一個(gè)基于 Spring 框架的快速開(kāi)發(fā)框架,旨在簡(jiǎn)化 Spring 應(yīng)用程序的開(kāi)發(fā)和部署。在本文中,我們將深入分析 SpringBoot 啟動(dòng)過(guò)程的源代碼,并提供必要的解釋和說(shuō)明

SpringBoot啟動(dòng)過(guò)程簡(jiǎn)介

SpringBoot應(yīng)用程序的啟動(dòng)過(guò)程可以分為以下幾個(gè)步驟:

  • 加載應(yīng)用程序上下文
  • 掃描應(yīng)用程序中的所有組件
  • 自動(dòng)配置應(yīng)用程序環(huán)境
  • 啟動(dòng)嵌入式Web服務(wù)器

在下面的章節(jié)中,我們將逐一分析這些步驟的源代碼。

加載應(yīng)用程序上下文

SpringBoot 應(yīng)用程序的上下文是一個(gè)包含所有應(yīng)用程序組件的容器。在啟動(dòng)過(guò)程中,SpringBoot 會(huì)加載并初始化這個(gè)容器。

這個(gè)步驟的源代碼在SpringApplication類(lèi)中。具體來(lái)說(shuō),SpringApplication類(lèi)的run方法是這個(gè)過(guò)程的入口點(diǎn)。在這個(gè)方法中,Spring Boot會(huì)通過(guò)調(diào)用createApplicationContext方法來(lái)創(chuàng)建應(yīng)用程序上下文。

下面是createApplicationContext方法的源代碼:

protected ConfigurableApplicationContext createApplicationContext() {
    Class<?> contextClass = this.applicationContextClass;
    if (contextClass == null) {
        try {
            switch (this.webApplicationType) {
                case SERVLET:
                    contextClass = Class.forName(DEFAULT_SERVLET_WEB_CONTEXT_CLASS);
                    break;
                case REACTIVE:
                    contextClass = Class.forName(DEFAULT_REACTIVE_WEB_CONTEXT_CLASS);
                    break;
                default:
                    contextClass = Class.forName(DEFAULT_CONTEXT_CLASS);
            }
        }
        catch (ClassNotFoundException ex) {
            throw new IllegalStateException(
                    "Unable to create a default ApplicationContext, " +
                    "please specify an ApplicationContextClass", ex);
        }
    }
    return (ConfigurableApplicationContext) BeanUtils.instantiateClass(contextClass);
}

在這個(gè)方法中,SpringBoot 會(huì)根據(jù)應(yīng)用程序類(lèi)型(Servlet或Reactive)選擇合適的上下文類(lèi)。然后,它會(huì)使用 Java 反射機(jī)制來(lái)實(shí)例化這個(gè)類(lèi)并返回一個(gè)可配置的應(yīng)用程序上下文對(duì)象。

掃描應(yīng)用程序中的所有組件

在上一步中,SpringBoot創(chuàng)建了應(yīng)用程序上下文。在這一步中,SpringBoot會(huì)掃描應(yīng)用程序中的所有組件并將它們注冊(cè)到應(yīng)用程序上下文中。

這個(gè)步驟的源代碼在SpringApplication類(lèi)中的scan方法中。具體來(lái)說(shuō),在這個(gè)方法中,SpringBoot 會(huì)創(chuàng)建一個(gè)SpringBootBeanDefinitionScanner對(duì)象,并使用它來(lái)掃描應(yīng)用程序中的所有組件。

下面是scan方法的源代碼:

private void scan(String... basePackages) {
    if (ObjectUtils.isEmpty(basePackages)) {
        return;
    }
    ClassPathScanningCandidateComponentProvider scanner = new ClassPathScanningCandidateComponentProvider(
            this.includeFilters, this.excludeFilters, this.resourceLoader);
    scanner.setResourceLoader(this.resourceLoader);
    scanner.setEnvironment(this.environment);
    scanner.setIncludeAnnotationConfig(this.useAnnotatedConfig);
    scanner.addExcludeFilter(new AbstractTypeHierarchyTraversingFilter(false, false) {
        @Override
        protected boolean matchClassName(String className) {
            return getExcludeClassNames().contains(className);
        }
    });
    for (String basePackage : basePackages) {
        scanner.findCandidateComponents(basePackage).forEach(this.componentDefinitions::add);
    }
}

在這個(gè)方法中,SpringBoot 會(huì)創(chuàng)建一個(gè)ClassPathScanningCandidateComponentProvider對(duì)象,并使用它來(lái)掃描應(yīng)用程序中的所有組件。這個(gè)對(duì)象會(huì)掃描指定包路徑下的所有類(lèi),并將它們轉(zhuǎn)換為 Spring 的 Bean 定義。這些 Bean 定義將被注冊(cè)到應(yīng)用程序上下文中。

自動(dòng)配置應(yīng)用程序環(huán)境

在上一步中,SpringBoot將應(yīng)用程序中的所有組件注冊(cè)到應(yīng)用程序上下文中。在這一步中,SpringBoot將自動(dòng)配置應(yīng)用程序環(huán)境,包括配置數(shù)據(jù)源、事務(wù)管理器、JPA等。

這個(gè)步驟的源代碼在SpringApplication類(lèi)中的configureEnvironment方法中。在這個(gè)方法中,Spring Boot會(huì)創(chuàng)建一個(gè)SpringApplicationRunListeners對(duì)象,并使用它來(lái)配置應(yīng)用程序環(huán)境。

下面是configureEnvironment方法的源代碼:

private void configureEnvironment(ConfigurableEnvironment environment, String[] args) {
    if (this.addCommandLineProperties) {
        ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
        environment.getPropertySources().addLast(new CommandLinePropertySource(applicationArguments));
    }
    this.listeners.environmentPrepared(environment);
    if (this.logStartupInfo) {
        this.logStartupInfo(environment);
    }
    ConfigurationPropertySources.attach(environment);
    Binder.get(environment).bind(ConfigurationPropertyName.EMPTY, Bindable.ofInstance(this.sources));
    if (!this.isCustomEnvironment) {
        EnvironmentConverter.configureEnvironment(environment, this.deduceEnvironmentClass());
    }
    this.listeners.environmentPrepared(environment);
}

在這個(gè)方法中,SpringBoot 會(huì)創(chuàng)建一個(gè)ApplicationArguments對(duì)象,并將其轉(zhuǎn)換為一個(gè)命令行屬性源。然后,它會(huì)調(diào)用listeners中的environmentPrepared方法來(lái)通知應(yīng)用程序環(huán)境已經(jīng)準(zhǔn)備好了。隨后,SpringBoot 會(huì)綁定屬性源到應(yīng)用程序環(huán)境中,并調(diào)用listeners中的environmentPrepared方法來(lái)通知應(yīng)用程序環(huán)境已經(jīng)準(zhǔn)備好了。

啟動(dòng)嵌入式Web服務(wù)器

在上一步中,SpringBoot 將應(yīng)用程序環(huán)境自動(dòng)配置完成。在這一步中,SpringBoot 將啟動(dòng)嵌入式Web服務(wù)器,以便應(yīng)用程序能夠提供 Web 服務(wù)。

這個(gè)步驟的源代碼在SpringApplication類(lèi)中的run方法中。具體來(lái)說(shuō),在這個(gè)方法中,SpringBoot 會(huì)根據(jù)應(yīng)用程序類(lèi)型(Servlet或Reactive)選擇合適的嵌入式Web服務(wù)器,并使用它來(lái)啟動(dòng)應(yīng)用程序。

下面是run方法的源代碼:

public ConfigurableApplicationContext run(String... args) {
    StopWatch stopWatch = new StopWatch();
    stopWatch.start();
    ConfigurableApplicationContext context = null;
    Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList<>();
    configureHeadlessProperty();
    SpringApplicationRunListeners listeners = getRunListeners(args);
    listeners.starting();
    try {
        ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
        ConfigurableEnvironment environment = prepareEnvironment(listeners, applicationArguments);
        configureIgnoreBeanInfo(environment);
        Banner printedBanner = printBanner(environment);
        context = createApplicationContext();
        exceptionReporters = getSpringFactoriesInstances(
                SpringBootExceptionReporter.class,
                new Class[] { ConfigurableApplicationContext.class }, context);
        prepareContext(context, environment, listeners, applicationArguments, printedBanner);
        refreshContext(context);
        afterRefresh(context, applicationArguments);
        stopWatch.stop();
        if (this.logStartupInfo) {
            new StartupInfoLogger(this.mainApplicationClass).logStarted(getApplicationLog(), stopWatch);
        }
        listeners.started(context);
        callRunners(context, applicationArguments);
    }
    catch (Throwable ex) {
        handleRunFailure(context, ex, exceptionReporters, listeners);
        throw new IllegalStateException(ex);
    }
    try {
        listeners.running(context);
    }
    catch (Throwable ex) {
        handleRunFailure(context, ex, exceptionReporters, null);
        throw new IllegalStateException(ex);
    }
    return context;
}

在這個(gè)方法中,SpringBoot 會(huì)使用一個(gè)StopWatch對(duì)象來(lái)計(jì)算應(yīng)用程序啟動(dòng)時(shí)間。然后,它會(huì)調(diào)用listeners中的starting方法來(lái)通知應(yīng)用程序即將啟動(dòng)。接著,SpringBoot 會(huì)準(zhǔn)備應(yīng)用程序環(huán)境,并使用它來(lái)創(chuàng)建應(yīng)用程序上下文。隨后,SpringBoot 會(huì)調(diào)用listeners中的started方法來(lái)通知應(yīng)用程序已經(jīng)啟動(dòng)。最后,SpringBoot 會(huì)調(diào)用callRunners方法來(lái)運(yùn)行所有的CommandLineRunnerApplicationRunner組件。

總結(jié)

在本文中,我們深入分析了 SpringBoot 應(yīng)用程序的啟動(dòng)過(guò)程的源代碼。我們了解了 SpringBoot 如何加載應(yīng)用程序上下文、掃描應(yīng)用程序中的所有組件、自動(dòng)配置應(yīng)用程序環(huán)境以及啟動(dòng)嵌入式Web服務(wù)器。這些步驟的源代碼展示了 SpringBoot 如何簡(jiǎn)化應(yīng)用程序的開(kāi)發(fā)和部署。

以上就是SpringBoot 之啟動(dòng)流程詳解的詳細(xì)內(nèi)容,更多關(guān)于SpringBoot啟動(dòng)流程的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Java后端接入微信小程序登錄功能(登錄流程)

    Java后端接入微信小程序登錄功能(登錄流程)

    這篇文章主要介紹了Java后端接入微信小程序登錄功能,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-06-06
  • Java輸入輸出流的使用詳細(xì)介紹

    Java輸入輸出流的使用詳細(xì)介紹

    本篇文章介紹了,在Java中輸入輸出流的使用詳細(xì)分析。需要的朋友參考下
    2013-04-04
  • SpringBoot服務(wù)設(shè)置禁止server.point端口的使用

    SpringBoot服務(wù)設(shè)置禁止server.point端口的使用

    本文主要介紹了SpringBoot服務(wù)設(shè)置禁止server.point端口的使用,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2024-01-01
  • idea 隱藏target,iml等不需要展示的文件(推薦)

    idea 隱藏target,iml等不需要展示的文件(推薦)

    這篇文章主要介紹了idea 隱藏target,iml等不需要展示的文件,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-11-11
  • Mybatis中的延遲加載詳細(xì)解析

    Mybatis中的延遲加載詳細(xì)解析

    這篇文章主要介紹了Mybatis中的延遲加載詳細(xì)解析,延遲加載就是在真正需要使用數(shù)據(jù)時(shí)才發(fā)起查詢,不用的時(shí)候不進(jìn)行查詢,按需加載(懶加載),需要的朋友可以參考下
    2023-12-12
  • 一篇文章超詳細(xì)的介紹Java繼承

    一篇文章超詳細(xì)的介紹Java繼承

    Java中的繼承是一種機(jī)制,表示為一個(gè)對(duì)象獲取父對(duì)象的所有屬性和行為,下面這篇文章主要給大家介紹了關(guān)于Java繼承的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-03-03
  • Java基于IO流讀取文件的方法

    Java基于IO流讀取文件的方法

    這篇文章主要介紹了Java基于IO流讀取文件的方法,涉及Java文件流操作的相關(guān)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下
    2015-10-10
  • Java實(shí)現(xiàn)系統(tǒng)限流的示例代碼

    Java實(shí)現(xiàn)系統(tǒng)限流的示例代碼

    限流是保障系統(tǒng)高可用的方式之一,也是大廠高頻面試題,它在微服務(wù)系統(tǒng)中,緩存、限流、熔斷是保證系統(tǒng)高可用的三板斧,所以本文我們就來(lái)聊聊如何實(shí)現(xiàn)系統(tǒng)限流吧
    2023-09-09
  • 在java中使用dom4j解析xml(示例代碼)

    在java中使用dom4j解析xml(示例代碼)

    鑒于目前的趨勢(shì),我們這里來(lái)講講Dom4j的基本用法,不涉及遞歸等復(fù)雜操作。Dom4j的用法很多,官網(wǎng)上的示例有那么點(diǎn)兒晦澀,這里就不寫(xiě)了
    2013-10-10
  • Maven是什么?Maven的概念+作用+倉(cāng)庫(kù)的介紹+常用命令的詳解

    Maven是什么?Maven的概念+作用+倉(cāng)庫(kù)的介紹+常用命令的詳解

    Maven是一個(gè)項(xiàng)目管理工具,它包含了一個(gè)對(duì)象模型。一組標(biāo)準(zhǔn)集合,一個(gè)依賴管理系統(tǒng)。和用來(lái)運(yùn)行定義在生命周期階段中插件目標(biāo)和邏輯.,本文給大家介紹Maven的概念+作用+倉(cāng)庫(kù)的介紹+常用命令,感興趣的的朋友跟隨小編一起看看吧
    2020-09-09

最新評(píng)論