首頁  >  文章  >  Java  >  SpringBoot啟動流程是什麼

SpringBoot啟動流程是什麼

PHPz
PHPz轉載
2023-05-21 23:14:548044瀏覽

SpringBoot啟動過程簡介

SpringBoot應用程式的啟動過程可以分為以下步驟:

  • 載入應用程式上下文

  • 掃描應用程式中的所有元件

  • 自動配置應用程式環境

  • 啟動嵌入式網路伺服器

#載入應用程式上下文

一個包含SpringBoot 應用程式所有元件的容器就是它的上下文。在啟動過程中,SpringBoot 會載入並初始化這個容器。

這個步驟的原始碼在SpringApplication類別中。具體來說,SpringApplication類別的run#方法是這個過程的入口點。在這個方法中,Spring Boot會透過呼叫createApplicationContext方法來建立應用程式上下文。

下面是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);
}

在這個方法中,SpringBoot 會根據應用程式類型(Servlet或Reactive)選擇合適的上下文類別。接著,使用 Java 反射機制來實例化該類別並傳回一個可配置的應用程式上下文物件。

掃描應用程式中的所有元件

在上一個步驟中,SpringBoot創建了應用程式上下文。在此階段,SpringBoot會掃描應用程式中的所有元件並將它們註冊到應用程式上下文中。

這個步驟的原始碼在SpringApplication類別中的scan方法中。具體來說,在這個方法中,SpringBoot 會建立一個SpringBootBeanDefinitionScanner對象,並使用它來掃描應用程式中的所有元件。

下面是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);
    }
}

在這個方法中,SpringBoot 會建立一個ClassPathScanningCandidateComponentProvider對象,並使用它來掃描應用程式中的所有元件。這個物件會掃描指定套件路徑下的所有類別,並將它們轉換為 Spring 的 Bean 定義。這些 Bean 定義將會註冊到應用程式上下文中。

自動配置應用程式環境

SpringBoot在前一步將應用程式中的所有元件註冊到應用程式上下文中。 SpringBoot會自動配置應用程式環境,其中包括資料來源、事務管理器和JPA配置。

這個步驟的原始碼在SpringApplication類別中的configureEnvironment方法中。在這個方法中,Spring Boot會建立一個SpringApplicationRunListeners對象,並使用它來配置應用程式環境。

下面是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);
}

在這個方法中,SpringBoot 會建立一個ApplicationArguments對象,並將其轉換為一個命令列屬性來源。然後,它會呼叫listeners中的environmentPrepared方法來通知應用程式環境已經準備好了。隨後,SpringBoot 會綁定屬性來源到應用程式環境中,並呼叫listeners中的environmentPrepared方法來通知應用程式環境已經準備好了。

啟動嵌入式Web伺服器

在前一步驟中,SpringBoot已自動完成了應用程式環境的設定。在這一步驟,SpringBoot將啟動內嵌式Web伺服器,以便應用程式提供Web服務。

這個步驟的原始碼在SpringApplication類別中的run方法中。具體來說,在這個方法中,SpringBoot 會根據應用程式類型(Servlet或Reactive)選擇合適的嵌入式Web伺服器,並使用它來啟動應用程式。

下面是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;
}

在這個方法中,SpringBoot 會使用一個StopWatch物件來計算應用程式啟動時間。然後,它會呼叫listeners中的starting方法來通知應用程式即將啟動。接著,SpringBoot 會準備應用程式環境,並使用它來建立應用程式上下文。隨後,SpringBoot 會呼叫listeners中的started方法來通知應用程式已經啟動。最後,SpringBoot 會呼叫callRunners方法來運行所有的CommandLineRunnerApplicationRunner元件。

以上是SpringBoot啟動流程是什麼的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:yisu.com。如有侵權,請聯絡admin@php.cn刪除