14-SpringBoot 有哪些優點?它和 Spring 有什麼區別?

Spring 和 Spring Boot 的區別很多新手容易搞混,從這道簡單的面試題也可以很輕易試探出你的 Java 基礎功底,如果連這個問題都答不上來的話,通常就沒有什麼下文了,因爲這已經是用人單位對面試者的最低要求了,所以本課時我們就來看一下二者的區別,以及 Spring Boot 的特性。

我們本課時的面試題是,Spring 和 Spring Boot 有什麼區別?Spring Boot 的優點有哪些?

典型回答

作爲 Java 開發人員對 Spring 框架都很熟悉,Spring 爲 Java 程序提供了全面的基礎架構支持,包含了很多非常實用的功能,如 Spring JDBC、Spring AOP、Spring ORM、Spring Test 等,這些模塊的出現,大大的縮短了應用程序的開發時間,同時提高了應用開發的效率。

Spring Boot 本質上是 Spring 框架的延伸和擴展,它的誕生是爲了簡化 Spring 框架初始搭建以及開發的過程,使用它可以不再依賴 Spring 應用程序中的 XML 配置,爲更快、更高效的開發 Spring 提供更加有力的支持。Spring Boot 具體的特性如下。

Spring Boot 特性一:更快速的構建能力

Spring Boot 提供了更多的 Starters 用於快速構建業務框架,Starters 可以理解爲啓動器,它包含了一系列可以集成到應用裏面的依賴包,你可以一站式集成 Spring 及其他技術,而不需要到處找依賴包。

例如在 Spring 中如果要創建 Web 應用程序的最小依賴項爲:

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-web</artifactId>
    <version>xxx</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-webmvc</artifactId>
    <version>xxx</version>
</dependency>

而 Spring Boot 只需要一個依賴項就可以來啓動和運行 Web 應用程序,如下所示:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

當我們添加了 Starter 模塊支持之後,在項目的構建期,它就會把所有其他依賴項將自動添加到項目中。

這樣的例子還有很多,比如測試庫,如果是 Spring 項目我們通常要添加 Spring Test、JUnit、Hamcrest 和 Mockito 庫;而如果是 Spring Boot 項目的話,只需要添加 spring-boot-starter-test 即可,它會自動幫我們把其他的依賴項添加到項目中。

常見的 Starters 有以下幾個:

  • spring-boot-starter-test
  • spring-boot-starter-web
  • spring-boot-starter-data-jpa
  • spring-boot-starter-thymeleaf
    點擊這裏訪問文檔,查看完整的 Starters 列表。

Spring Boot 特性二:起步依賴

Spring Boot 提供了起步依賴,也就是在創建 Spring Boot 時可以直接勾選依賴模塊,這樣在項目初始化時就會把相關依賴直接添加到項目中,大大縮短了查詢並添加依賴的時間,如下圖所示:
在這裏插入圖片描述

Spring Boot 特性三:內嵌容器支持

Spring Boot 內嵌了 Tomcat、Jetty、Undertow 三種容器,其默認嵌入的容器是 Tomcat,這個在我們啓動 Spring Boot 項目的時候,在控制檯上就能看到,具體信息如下:

o.s.b.w.embedded.tomcat.TomcatWebServer :Tomcat started on port(s):> 8080 (http) with context path ‘’

可以看出 Spring Boot 默認使用的是 Tomcat 容器啓動的。

我們可以通過修改 pom.xml 來移除內嵌的 Tomcat 更換爲其他的容器,比如更換爲 Jetty 容器,配置如下:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    <!-- 移處 Tomcat -->
    <exclusions>
        <exclusion>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-tomcat</artifactId>
        </exclusion>
    </exclusions>
</dependency>
<!-- 移處 jetty 容器 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-jetty</artifactId>
</dependency>

當我們添加完成之後,再重新生成 pom.xml 文件,然後再啓動 Spring Boot 項目容器信息就變了,如下所示:

o.e.jetty.server.AbstractConnector: Started ServerConnector@53f9009d{HTTP/1.1, (http/1.1)}{0.0.0.0:8080}
o.s.b.web.embedded.jetty.JettyWebServer

可以看出 Spring Boot 使用了我們指定的 Jetty 容器啓動了。

Spring Boot 特性四:Actuator 監控

Spring Boot 自帶了 Actuator 監控功能,主要用於提供對應用程序監控,以及控制的能力,比如監控應用程序的運行狀況,或者內存、線程池、Http 請求統計等,同時還提供了關閉應用程序等功能。

Actuator 提供了 19 個接口,接口請求地址和代表含義如下表所示:
在這裏插入圖片描述

考點分析

很多人都知道 Spring Boot 是基於 Spring 的,使用它可以更加快速高效的構建 Spring,然而當面試官問到 Spring Boot 是如何高效構建 Spring 時,可能大部分人回答不上來了,上面講解的 Spring Boot 四大特性基本涵蓋了此問題的答案。如果面試官繼續追問更深的細節的話,可能會問到關於 Spring Boot 執行的源碼細節,比如 Spring Boot 的啓動流程是怎麼樣的?

知識擴展

Spring Boot 啓動源碼分析

我們知道 Spring Boot 程序的入口是 SpringApplication.run(Application.class, args) 方法,那麼就從 run() 方法開始分析吧,它的源碼如下:

public ConfigurableApplicationContext run(String... args) {
    // 1.創建並啓動計時監控類
    StopWatch stopWatch = new StopWatch();
    stopWatch.start();
    // 2.聲明應用上下文對象和異常報告集合
    ConfigurableApplicationContext context = null;
    Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList();
    // 3.設置系統屬性 headless 的值
    this.configureHeadlessProperty();
    // 4.創建所有 Spring 運行監聽器併發布應用啓動事件
    SpringApplicationRunListeners listeners = this.getRunListeners(args);
    listeners.starting();
    Collection exceptionReporters;
    try {
        // 5.處理 args 參數
        ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
        // 6.準備環境
        ConfigurableEnvironment environment = this.prepareEnvironment(listeners, applicationArguments);
        this.configureIgnoreBeanInfo(environment);
        // 7.創建 Banner 的打印類
        Banner printedBanner = this.printBanner(environment);
        // 8.創建應用上下文
        context = this.createApplicationContext();
        // 9.實例化異常報告器
        exceptionReporters = this.getSpringFactoriesInstances(SpringBootExceptionReporter.class, new Class[]{ConfigurableApplicationContext.class}, context);
        // 10.準備應用上下文
        this.prepareContext(context, environment, listeners, applicationArguments, printedBanner);
        // 11.刷新應用上下文
        this.refreshContext(context);
        // 12.應用上下文刷新之後的事件的處理
        this.afterRefresh(context, applicationArguments);
        // 13.停止計時監控類
        stopWatch.stop();
        // 14.輸出日誌記錄執行主類名、時間信息
        if (this.logStartupInfo) {
            (new StartupInfoLogger(this.mainApplicationClass)).logStarted(this.getApplicationLog(), stopWatch);
        }
        // 15.發佈應用上下文啓動完成事件
        listeners.started(context);
        // 16.執行所有 Runner 運行器
        this.callRunners(context, applicationArguments);
    } catch (Throwable var10) {
        this.handleRunFailure(context, var10, exceptionReporters, listeners);
        throw new IllegalStateException(var10);
    }
    try {
        // 17.發佈應用上下文就緒事件
        listeners.running(context);
        // 18.返回應用上下文對象
        return context;
    } catch (Throwable var9) {
        this.handleRunFailure(context, var9, exceptionReporters, (SpringApplicationRunListeners)null);
        throw new IllegalStateException(var9);
    }
}

從以上源碼可以看出 Spring Boot 的啓動總共分爲以下 18 個步驟。

Spring Boot 的啓動流程

1.創建並啓動計時監控類

此計時器是爲了監控並記錄 Spring Boot 應用啓動的時間的,它會記錄當前任務的名稱,然後開啓計時器。

2.聲明應用上下文對象和異常報告集合

此過程聲明瞭應用上下文對象和一個異常報告的 ArrayList 集合。

3.設置系統屬性 headless 的值

設置 Java.awt.headless = true,其中 awt(Abstract Window Toolkit)的含義是抽象窗口工具集。設置爲 true 表示運行一個 headless 服務器,可以用它來作一些簡單的圖像處理。

4.創建所有 Spring 運行監聽器併發布應用啓動事件

此過程用於獲取配置的監聽器名稱並實例化所有的類。

5.初始化默認應用的參數類

也就是說聲明並創建一個應用參數對象。

6.準備環境

創建配置並且綁定環境(通過 property sources 和 profiles 等配置文件)。

7.創建 Banner 的打印類

Spring Boot 啓動時會打印 Banner 圖片,如下圖所示:
在這裏插入圖片描述
此 banner 信息是在 SpringBootBanner 類中定義的,我們可以通過實現 Banner 接口來自定義 banner 信息,然後通過代碼 setBanner() 方法設置 Spring Boot 項目使用自己自定義 Banner 信息,或者是在 resources 下添加一個 banner.txt,把 banner 信息添加到此文件中,就可以實現自定義 banner 的功能了。

8.創建應用上下文

根據不同的應用類型來創建不同的 ApplicationContext 上下文對象。

9.實例化異常報告器

它調用的是 getSpringFactoriesInstances() 方法來獲取配置異常類的名稱,並實例化所有的異常處理類。

10.準備應用上下文

此方法的主要作用是把上面已經創建好的對象,傳遞給 prepareContext 來準備上下文,例如將環境變量 environment 對象綁定到上下文中、配置 bean 生成器以及資源加載器、記錄啓動日誌等操作。

11.刷新應用上下文

此方法用於解析配置文件,加載 bean 對象,並且啓動內置的 web 容器等操作。

12.應用上下文刷新之後的事件處理

這個方法的源碼是空的,可以做一些自定義的後置處理操作。

13.停止計時監控類

停止此過程第一步中的程序計時器,並統計任務的執行信息。

14.輸出日誌信息

把相關的記錄信息,如類名、時間等信息進行控制檯輸出。

15.發佈應用上下文啓動完成事件

觸發所有 SpringApplicationRunListener 監聽器的 started 事件方法。

16.執行所有 Runner 運行器

執行所有的 ApplicationRunner 和 CommandLineRunner 運行器。

17.發佈應用上下文就緒事件

觸發所有的 SpringApplicationRunListener 監聽器的 running 事件。

18.返回應用上下文對象

到此爲止 Spring Boot 的啓動程序就結束了,我們就可以正常來使用 Spring Boot 框架了。

小結

本課時首先講了 Spring 和 Spring Boot 的區別,Spring Boot 本質上是 Spring 的延伸,它是基於 Spring 的,它爲快速構建和開發 Spring 提供了有力的支撐;接着介紹了 Spring Boot 的四大特性:更快速的構建能力、起步依賴、內嵌容器支持、Actuator 監控支持等,最後 還介紹了 Spring Boot 啓動的 18 個步驟。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章