互聯網的寒冬下各大一線互聯網公司還在用SpringBoot這是為什麼?

来源:https://www.cnblogs.com/MonsterJ/archive/2020/07/15/13307490.html
-Advertisement-
Play Games

引言 現在各大技術社區 Spring Boot 的文章越來越多,Spring Boot 相關的圖文、視頻教程越來越多,使用 Spring Boot 的互聯網公司也越來越多; Java 程式員現在出去面試, Spring Boot 已經成了必問的內容。 一切都在證明,Spring Boot 已經成為了 ...


引言

現在各大技術社區 Spring Boot 的文章越來越多,Spring Boot 相關的圖文、視頻教程越來越多,使用 Spring Boot 的互聯網公司也越來越多; Java 程式員現在出去面試, Spring Boot 已經成了必問的內容。

一切都在證明,Spring Boot 已經成為了 Java 程式員必備的技能。並且可以預見的是未來 Spring Boot 的發展還會更好。

所以對Java程式員來說其中不乏說對 Spring Boot 非常熟悉的,然後當問到一些 Spring Boot 核心功能和原理的時候,沒人能說得上來,或者說不到點上,可以說一個問題就問趴下了!(問題:你能講下為什麼我們要用 Spring Boot 嗎?)

相信我,上面這些類似的問題,90%有經驗的Java程式員超都曾遇見過!但很少有系統化的回答。

因此,總結了這份Spring Boot核心知識點實戰教程,通過這份教程,帶你梳理Spring Boot 技術體系。

文末有彩蛋~
在這裡插入圖片描述

Spring Boot2教程
在Spring Boot項目中,正常來說是不存在XML配置,這是因為Spring Boot不推薦使用 XML ,註意,並非不支持,Spring Boot 推薦開發者使用 Java 配置來搭建框架,Spring Boot 中,大量的自動化配置都是通過 Java 配置來實現的,這一套實現方案,我們也可以自己做,即自己也可以使用純 Java 來搭建一個 SSM 環境,即在項目中,不存在任何 XML 配置,包括 web.xml 。

環境要求:

使用純 Java 來搭建 SSM 環境,要求 Tomcat 的版本必須在 7 以上。

在這裡插入圖片描述

1、創建工程

創建一個普通的 Maven工程(註意,這裡可以不必創建Web工程),並添加SpringMVC的依賴,同時,這裡環境的搭建需要用到 Servlet ,所以我們還需要引入 Servlet 的依賴(一定不能使用低版本的Servlet),最終的 pom.xml 文件如下:

<dependency>
	  <groupId>org.springframework</groupId>
	  <artifactId>spring-webmvc</artifactId>
	  <version>5.1.6.RELEASE</version>
</dependency>
<dependency>
	  <groupId>javax.servlet</groupId>
	  <artifactId>javax.servlet-api</artifactId>
	  <version>4.0.1</version>
	  <scope>provided</scope>
</dependency>

2 、添加 Spring 配置

工程創建成功之後,首先添加 Spring 的配置文件,如下:

@Configuration
@ComponentScan(basePackages = "org.javaboy", useDefaultFilters = true,
excludeFilters = {@ComponentScan.Filter(type = FilterType.ANNOTATION, classes =
Controller.class)})
public class SpringConfig {
}

關於這個配置,我說如下幾點:

@Configuration 註解表示這是一個配置類,在我們這裡,這個配置的作用類似於applicationContext.xml

@ComponentScan 註解表示配置包掃描,裡邊的屬性和 xml 配置中的屬性都是一一對應的,useDefaultFilters 表示使用預設的過濾器,然後又除去 Controller 註解,即在 Spring 容器中掃描除了 Controller 之外的其他所有 Bean 。

3、 添加 SpringMVC 配置

接下來再來創建 springmvc 的配置文件:

@Configuration
@ComponentScan(basePackages = "org.javaboy",useDefaultFilters =
false,includeFilters = {@ComponentScan.Filter(type =
FilterType.ANNOTATION,classes = Controller.class)})
public class SpringMVCConfig {
}

註意,如果不需要在SpringMVC中添加其他的額外配置,這樣就可以了。即視圖解析器、JSON解析、文件上傳......等等,如果都不需要配置的話,這樣就可以了。

在這裡插入圖片描述

4、配置 web.xml

此時,我們並沒 web.xml 文件,這時,我們可以使用Java代碼去代替 web.xml 文件,這裡會用到WebApplicationInitializer ,具體定義如下:

public class WebInit implements WebApplicationInitializer {
  public void onStartup(ServletContext servletContext) throws ServletException
{
    //首先來載入 SpringMVC 的配置文件
    AnnotationConfigWebApplicationContext ctx = new
AnnotationConfigWebApplicationContext();
    ctx.register(SpringMVCConfig.class);
    // 添加 DispatcherServlet
    ServletRegistration.Dynamic springmvc =
servletContext.addServlet("springmvc", new DispatcherServlet(ctx));
    // 給 DispatcherServlet 添加路徑映射
    springmvc.addMapping("/");
    // 給 DispatcherServlet 添加啟動時機
    springmvc.setLoadOnStartup(1);
 }
}

WebInit 的作用類似於 web.xml,這個類需要實現 WebApplicationInitializer 介面,並實現介面中的方法,當項目啟動時,onStartup 方法會被自動執行,我們可以在這個方法中做一些項目初始化操作,例如載入 SpringMVC 容器,添加過濾器,添加 Listener、添加 Servlet 等。

註意:

由於我們在WebInit中只是添加了SpringMVC的配置,這樣項目在啟動時只會去載入SpringMVC容器,而不會去載入 Spring 容器,如果一定要載入 Spring 容器,需要我們修改 SpringMVC 的配置,在SpringMVC 配置的包掃描中也去掃描 @Configuration 註解,進而載入 Spring 容器,還有一種方案可以解決這個問題,就是直接在項目中捨棄 Spring 配置,直接將所有配置放到 SpringMVC 的配置中來完成,這個在 SSM 整合時是沒有問題的,在實際開發中,較多採用第二種方案,第二種方案,SpringMVC 的配置如下:

@Configuration
@ComponentScan(basePackages = "org.javaboy")
public class SpringMVCConfig {
}

這種方案中,所有的註解都在 SpringMVC 中掃描,採用這種方案的話,則 Spring 的配置文件就可以刪除了。

5、測試

最後,添加一個 HelloController ,然後啟動項目進行測試:

@RestController
public class HelloController {
  @GetMapping("/hello")
  public String hello() {
    return "hello";
 }
}

啟動項目,訪問介面,結果如下:

在這裡插入圖片描述

Spring Boot全局異常處理

在Spring Boot項目中 ,異常統一處理,可以使用Spring中@ControllerAdvice來統一處理,也可以自己來定義異常處理方案。Spring Boot 中,對異常的處理有一些預設的策略,我們分別來看。

預設情況下,Spring Boot 中的異常頁面 是這樣的:

在這裡插入圖片描述

我們從這個異常提示中,也能看出來,之所以用戶看到這個頁面,是因為開發者沒有明確提供一個/error 路徑,如果開發者提供了 /error 路徑 ,這個頁面就不會展示出來,不過在 Spring Boot 中,提供/error 路徑實際上是下下策,Spring Boot本身在處理異常時,也是當所有條件都不滿足時,才會去找 /error 路徑。那麼我們就先來看看,在 Spring Boot 中,如何自定義 error 頁面,整體上來說,可以分為兩種,一種是靜態頁面,另一種是動態頁面。

靜態異常頁面

自定義靜態異常頁面,又分為兩種,第一種 是使用HTTP響應碼來命名頁面,例如404.html、405.html、500.html ....,另一種就是直接定義一個 4xx.html,表示400-499 的狀態都顯示這個異常頁面,5xx.html 表示 500-599 的狀態顯示這個異常頁面。

預設是在 classpath:/static/error/ 路徑下定義相關頁面:

在這裡插入圖片描述

此時,啟動項目,如果項目拋出 500 請求錯誤,就會自動展示 500.html 這個頁面,發生 404 就會展示404.html 頁面。如果異常展示頁面既存在 5xx.html,也存在 500.html ,此時,發生500異常時,優先展示 500.html 頁面。

動態異常頁面

動態的異常頁面定義方式和靜態的基本 一致,可以採用的頁面模板有 jsp、freemarker、thymeleaf。

動態異常頁面,也支持 404.html 或者 4xx.html ,但是一般來說,由於動態異常頁面可以直接展示異常詳細信息,所以就沒有必要挨個枚舉錯誤了 ,直接定義 4xx.html(這裡使用thymeleaf模板)或者5xx.html 即可。

註意,動態頁面模板,不需要開發者自己去定義控制器,直接定義異常頁面即可 ,Spring Boot 中自帶的異常處理器會自動查找到異常頁面。

頁面定義如下:
在這裡插入圖片描述

頁面內容如下:

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>
<h1>5xx</h1>
<table border="1">
  <tr>
    <td>path</td>
    <td th:text="${path}"></td>
  </tr>
  <tr>
    <td>error</td>
    <td th:text="${error}"></td>
  </tr>
  <tr>
    <td>message</td>
    <td th:text="${message}"></td>
  </tr>
  <tr>
    <td>timestamp</td>
    <td th:text="${timestamp}"></td>
  </tr>
  <tr>
    <td>status</td>
    <td th:text="${status}"></td>
  </tr>
</table>
</body>
</html>

預設情況下,完整的異常信息就是這5條,展示 效果如下 :
在這裡插入圖片描述

如果動態頁面和靜態頁面同時定義了異常處理頁面,例如 classpath:/static/error/404.html 和classpath:/templates/error/404.html 同時存在時,預設使用動態頁面。即完整的錯誤頁面查找

方式應該是這樣:

發生了 500 錯誤-->查找動態 500.html 頁面-->查找靜態 500.html --> 查找動態 5xx.html-->查找靜態5xx.html。

在這裡插入圖片描述

自定義異常數據

預設情況下,在 Spring Boot 中,所有的異常數據其實就是上文所展示出來的 5 條數據,這 5 條數據定義在 org.springframework.boot.web.reactive.error.DefaultErrorAttributes 類中,具體定義在 getErrorAttributes 方法中 :

public Map<String, Object> getErrorAttributes(ServerRequest request,
        boolean includeStackTrace) {
    Map<String, Object> errorAttributes = new LinkedHashMap<>();
    errorAttributes.put("timestamp", new Date());
    errorAttributes.put("path", request.path());
    Throwable error = getError(request);
    HttpStatus errorStatus = determineHttpStatus(error);
    errorAttributes.put("status", errorStatus.value());
    errorAttributes.put("error", errorStatus.getReasonPhrase());
    errorAttributes.put("message", determineMessage(error));
    handleException(errorAttributes, determineException(error),
includeStackTrace);
    return errorAttributes;
}

DefaultErrorAttributes 類本身則是在

org.springframework.boot.autoconfigure.web.servlet.error.ErrorMvcAutoConfiguration 異常自動配置類中定義的,如果開發者沒有自己提供一個 ErrorAttributes 的實例的話,那麼 Spring Boot 將自動提供一個 ErrorAttributes 的實例,也就是 DefaultErrorAttributes 。

基於此 ,開發者自定義 ErrorAttributes 有兩種方式 :

  1. 直接實現 ErrorAttributes 介面

  2. 繼承 DefaultErrorAttributes(推薦),因為 DefaultErrorAttributes 中對異常數據的處理已經完成,開發者可以直接使用。

具體定義如下:

@Component
public class MyErrorAttributes  extends DefaultErrorAttributes {
  @Override
  public Map<String, Object> getErrorAttributes(WebRequest webRequest, boolean
includeStackTrace) {
    Map<String, Object> map = super.getErrorAttributes(webRequest,
includeStackTrace);
    if ((Integer)map.get("status") == 500) {
      map.put("message", "伺服器內部錯誤!");
   }
    return map;
 }
}

定義好的 ErrorAttributes 一定要註冊成一個 Bean ,這樣,Spring Boot 就不會使用預設的DefaultErrorAttributes 了,運行效果如下圖:

在這裡插入圖片描述

自定義異常視圖

異常視圖預設就是前面所說的靜態或者動態頁面,這個也是可以自定義的,首先 ,預設的異常視圖載入邏輯在 org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController 類的errorHtml 方法中,這個方法用來返回異常頁面+數據,還有另外一個 error 方法,這個方法用來返回異常數據(如果是 ajax 請求,則該方法會被觸發)。

@RequestMapping(produces = MediaType.TEXT_HTML_VALUE)
public ModelAndView errorHtml(HttpServletRequest request,
        HttpServletResponse response) {
    HttpStatus status = getStatus(request);
    Map<String, Object> model =
Collections.unmodifiableMap(getErrorAttributes(
            request, isIncludeStackTrace(request,
MediaType.TEXT_HTML)));
    response.setStatus(status.value());
    ModelAndView modelAndView = resolveErrorView(request, response, status,
model);
    return (modelAndView != null) ? modelAndView : new ModelAndView("error",
model);
}

在該方法中 ,首先會通過 getErrorAttributes 方法去獲取異常數據(實際上會調用到 ErrorAttributes的實例 的 getErrorAttributes 方法),然後調用 resolveErrorView 去創建一個 ModelAndView ,如果這裡創建失敗,那麼用戶將會看到預設的錯誤提示頁面。

正常情況下, resolveErrorView 方法會來到 DefaultErrorViewResolver 類的 resolveErrorView 方法中:

@Override
public ModelAndView resolveErrorView(HttpServletRequest request, HttpStatus
status,
        Map<String, Object> model) {
    ModelAndView modelAndView = resolve(String.valueOf(status.value()),
model);
    if (modelAndView == null && SERIES_VIEWS.containsKey(status.series())) {
        modelAndView = resolve(SERIES_VIEWS.get(status.series()),
model);
   }
    return modelAndView;
}

在這裡,首先以異常響應碼作為視圖名分別去查找動態頁面和靜態頁面,如果沒有查找到,則再以 4xx或者 5xx 作為視圖名再去分別查找動態或者靜態頁面。

要自定義異常視圖解析,也很容易 ,由於 DefaultErrorViewResolver 是在ErrorMvcAutoConfiguration 類中提供的實例,即開發者沒有提供相關實例時,會使用預設的DefaultErrorViewResolver ,開發者提供了自己的 ErrorViewResolver 實例後,預設的配置就會失效,因此,自定義異常視圖,只需要提供 一個 ErrorViewResolver 的實例即可:

@Component
public class MyErrorViewResolver extends DefaultErrorViewResolver {
  public MyErrorViewResolver(ApplicationContext applicationContext,
ResourceProperties resourceProperties) {
    super(applicationContext, resourceProperties);
 }
  @Override
  public ModelAndView resolveErrorView(HttpServletRequest request, HttpStatus
status, Map<String, Object> model) {
    return new ModelAndView("/aaa/123", model);
 }
}

實際上,開發者也可以在這裡定義異常數據(直接在 resolveErrorView 方法重新定義一個 model ,將參數中的model 數據拷貝過去並修改,註意參數中的 model 類型為 UnmodifiableMap,即不可以直接修改),而不需要自定義 MyErrorAttributes。定義完成後,提供一個名為 123 的視圖,如下圖:

在這裡插入圖片描述

如此之後,錯誤試圖就算定義成功了。

總結

實際上也可以自定義異常控制器 BasicErrorController ,不過我覺得這樣太大動干戈了,沒必要,前面幾種方式已經可以滿足我們的大部分開發需求了。如果是前後端分離架構,異常處理還有其他一些處理方案,這個以後和大家聊。

在這裡插入圖片描述

篇幅有限,其他內容就不在這裡一一展示了,這份Spring Boot實戰教程已整理成一份PDF文檔,共有200多頁。

關註公眾號:程式零世界,回覆 666 獲取這份整理好的Spring Boot實戰教程。

在這裡插入圖片描述

最後

歡迎大家一起交流,喜歡文章記得點ge 贊喲,感謝支持!
file


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 列表生成式即List Comprehensions,是Python內置的非常簡單卻強大的可以用來創建list的生成式。 通常我們在迴圈遍歷一個列表時,都是通過for迴圈來完成 L = [] for i in range(1,11) L.append(x*x) 結果如下: [1,4,9,16,25,3 ...
  • 1、一切皆對象 一、 類也是對象 在大多數編程語言中,類就是一組用來描述如何生成一個對象的代碼段,在Python中這一點仍然成立。但是,Python中的類還遠不止如此。類同樣也是一種對象。只要你使用關鍵字class,Python解釋器在執行的時候就會創建一個對象。下麵的代碼段: class MyCl ...
  • 一、基本概念 程式(program): 是為完成特定任務、用某種語言編寫的一組指令的集合。即指一 段靜態的代碼,靜態對象。 進程(process):是程式的一次執行過程,或是正在運行的一個程式。是一個動態 的過程:有它自身的產生、存在和消亡的過程。——生命周期 運行中的QQ,運行中的MP3播放器 程 ...
  • 簡介 道可道,非常道。這裡常道指的永恆不變的道理,常有不變的意思。顧名思義和變數相比,常量在聲明之後就不可改變,它的值是在編譯期間就確定的。 下麵簡單的聲明一個常量: const p int = 1 聲明常量的時候可以指定類型也可以類似:=簡單聲明一樣,不指定類型如下: const p = 1 也可 ...
  • from typing import Listclass Solution: # 第一種是我想的辦法 def singleNumber(self, nums: List[int]) -> int: # 首先進行排序 nums.sort() # 然後判斷重覆的數字,數組中的數字必定為奇數個, # 如果 ...
  • Pydantic 是一個使用Python類型提示來進行數據驗證和設置管理的庫。Pydantic定義數據應該如何使用純Python規範用併進行驗證。PEP 484 從Python3.5開始引入了類型提示的功能,PEP 526 使用Python3.6中的變數註釋語法對其進行了拓展。Pydantic使用這 ...
  • # 二叉搜索樹的特點是左子樹小於根節點,右子樹大於根節點。# 因此當根節點為i的時候,左子樹的值為1:i-1,右子樹為i+1:n# 當節點為n的時候所有的能夠組成的樹為左子樹個數乘以右子樹個數。class Solution: def numTrees(self, n: int) -> int: dp ...
  • update 2020/7/15 優化了一下 \(markdown\) 的用法,增加了前面的題目描述。 題目: 題目描述 從加里敦大學城市規劃專業畢業的小明來到了一個地區城市規劃局工作。這個地區一共有 \(n\) 座城市,\(n-1\) 條高速公路,保證了任意兩運城市之間都可以通過高速公路相互可達, ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...