成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

用了這么多年的 SpringBoot ,你知道什么是 SpringBoot 的 Web 類型推斷嗎?

開發 架構
Spring? 的出現給 Java? 程序員帶來了春天,而 SpringBoot? 框架的出現又極大的加速了程序員的開發效率,然而很多時候我們在使用她的便利的同時會缺少對于底層系統實現的把握,希望這篇文章弄幫助大家對 SpringBoot 產生更多的理解。

用了這么多年的 SpringBoot 那么你知道什么是 SpringBoot 的 web 類型推斷嗎?

估計很多小伙伴都不知道,畢竟平時開發做項目的時候做的都是普通的 web 項目并不需要什么特別的了解,不過抱著學習的心態,阿粉今天帶大家看一下什么是 SpringBoot 的 web 類型推斷。

SpringBoot 的 web 類型有哪些

既然是web 類型推斷,那我們肯定要知道 SpringBoot 支持哪些類型,然后才能分析是怎樣進行類型推斷的。

根據官方的介紹 SpringBoot 的 web 類型有三種,分別是,NONE、SERVLET 和 REACTIVE,定義在枚舉 WebApplicationType 中,這三種類型分別代表了三種含義:

  • NONE?:不是一個 web? 應用,不需要啟動內置的 web 服務器;
  • SERVLET?:基于 servlet? 的 web? 應用,需要啟動一個內置的 servlet 服務器;
  • REACTIVE?:一個 reactive? 的 web? 應用,需要啟動一個內置的 reactive 服務器;

public enum WebApplicationType {
NONE,
SERVLET,
REACTIVE;
}

web 類型推斷

上面提到了 SpringBoot 的三種 web 類型,接下來我們先通過代碼驗證一下,然后再分析一下 SpringBoot 是如何進行類型推斷的。

首先我們通過在 https://start.spring.io/ 快速的構建三種類型的項目,三種類型的項目配置除了依賴不一樣之外,其他都一樣,如下所示

None web

圖片

none

下載后的項目文件 pom 中對應的依賴為

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

Servlet web

圖片

servlet

下載后的項目文件 pom 中對應的依賴為

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

Reactive web

圖片

reactive

下載后的項目文件 pom 中對應的依賴為

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

接下來我們依次啟動三個項目看看有什么區別,

啟動 None web

圖片

none-web

通過啟動日志我們可以看到,在 None web 類型下,應用啟動運行后就自動關閉了,并沒有啟動內置的 web 服務器,也沒有監聽任何端口。接下來我們看看其他兩種類型 web 的啟動日志都是怎么樣的。

啟動 Servlet web

圖片

servelt-web

通過啟動日志我們可以看到這里啟動了內置的 Tomcat Servlet 服務器,監聽了 8080 端口,應用程序并不會像 None 類型一樣,啟動后就自動關閉。

啟動 Reactive web

圖片

reactive-web

通過啟動日志我們可以看到,這里啟動了內置的 Netty 服務器,并監聽在 8080 端口上(如果啟動失敗記得把上面 servlet web 關閉,不然端口會沖突)。

三種類型的服務我們都成功啟動了,那么接下來的問題就是 SpringBoot 是如何判斷出該使用哪種類型的呢?

這三個服務我們只有依賴不一樣,很明顯肯定和依賴有關系,接下來我們就來研究一下 SpringBoot 是如何實現的。

SpringBoot Web 類型推斷原理

我們在 main 方法中點擊 run 方法,

public static ConfigurableApplicationContext run(Class<?>[] primarySources, String[] args){
return new SpringApplication(primarySources).run(args);
}

在構造函數中我們可以看到其中有這么一行 this.webApplicationType = WebApplicationType.deduceFromClasspath();根據屬性名稱我們可以推斷,web 類型就是根據 WebApplicationType.deduceFromClasspath(); 這個靜態方法來判斷的。接下來我們看下這個方法的細節。

圖片

圖片

如上圖所示,可以看到 SpringBoot 底層是通過 ClassUtils.isPresent() 方法來判斷對應的 web 類型類是否存在來判斷 web 類型的。

在前類路徑下面如果當 org.springframework.web.reactive.DispatcherHandler 存在而且 org.springframework.web.servlet.DispatcherServlet 和 org.glassfish.jersey.servlet.ServletContainer 都不存在的時候說明當前應用 web 類型為 Reactive。

當 javax.servlet.Servlet 和 org.springframework.web.context.ConfigurableWebApplicationContext 任何一個不存在的時候,就說明當前應用是 None 類型非 web 應用。否則當前應用就為 Servlet 類型。

而我們再看這個 ClassUtils.isPresent() 方法,可以發現底層是通過 className 在類路徑上加載對應的類,如果存在則返回 true,如果不存在則返回 false。

圖片

因此這也解釋了為什么我們在 pom 文件中只要加入對應的依賴就可以直接得到相應的 web 類型了,因為當我們在 pom 中加入相應的依賴過后,類路徑里面就存在了前面判斷的對應的類,再通過 ClassUtils.isPresent() 就判斷出來當前應用屬于那種 web 類型了。

內置服務器是如何創建的

知道了 SpringBoot 是如何進行 web 類型推斷的,那么接下來一個問題就是 SpringBoot 是如何根據 web 類型進行相應內置 web 服務器的啟動的呢?這里我們以 Reactive web 為例進行調試追蹤。

首先我們在 SpringApplication 的 run 方法 createApplicationContext() 下一行打斷點,可以發現創建成功的 context 類型為 AnnotationConfigReactiveWebServerApplicationContext  很明顯在這一步的時候就已經根據類型推斷得到了當前的應用 web 類型為 Reactive,并且根據 web 類型創建出了對應的 ApplicationContext。

圖片

reactive-web

緊接著我們進入 org.springframework.boot.SpringApplication#refreshContext 方法,最后我們可以進入到 org.springframework.boot.web.reactive.context.ReactiveWebServerApplicationContext#refresh 方法中,因為 AnnotationConfigReactiveWebServerApplicationContext   繼承了 ReactiveWebServerApplicationContext。

圖片

繼續通過引用關系,我們可以找到 org.springframework.boot.web.reactive.context.ReactiveWebServerApplicationContext#onRefresh 方法,而在這個方法里面我們就會發現了如下代碼,此處就會創建一個 webServer。

圖片

具體創建的方法在 WebServerManager 里面,跟著繼續往下找我們可以找到 createHttpServer() 方法,在 createHttpServer() 方法中就創建了 HttpServer 并且綁定了默認的端口 8080。具體過程,如下幾張接入所示,感興趣的可以自行跟蹤 debug,至此一個 Reactive 內置服務器就創建成功了,同樣的 Servlet 服務器也是類似的。

圖片

圖片

圖片

圖片

總結

Spring 的出現給 Java 程序員帶來了春天,而 SpringBoot 框架的出現又極大的加速了程序員的開發效率,然而很多時候我們在使用她的便利的同時會缺少對于底層系統實現的把握,希望這篇文章弄幫助大家對 SpringBoot 產生更多的理解。

責任編輯:武曉燕 來源: Java極客技術
相關推薦

2023-11-13 08:49:54

2023-09-28 11:45:09

泛型類對象編譯器

2021-04-16 11:15:22

蘋果手機屏幕

2020-07-21 18:37:14

代碼條件變量

2018-10-06 21:51:37

代碼SOLID編程

2015-03-27 10:20:41

谷歌地圖谷歌偉大

2020-05-29 14:18:12

Java泛型數據

2020-05-22 13:35:39

Java 開發者代碼

2021-09-08 22:38:56

區塊鏈公有鏈網絡

2024-02-20 08:09:51

Java 8DateUtilsDate工具類

2021-10-07 23:24:21

手機關機重啟

2021-09-11 22:56:58

微信功能技巧

2024-02-26 08:19:00

WebSpring容器

2021-05-21 05:24:03

Excel數據技巧

2021-02-03 08:24:32

JavaScript技巧經驗

2024-03-01 17:01:15

GraphQL后端

2017-11-30 07:30:27

程序員代碼軟件世界觀

2018-10-07 06:30:40

代碼設計模式面向對象原則

2021-04-27 15:13:20

Java開發語言

2021-09-13 10:03:54

藍牙連接藍牙藍牙設備
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 成人国产免费视频 | 少妇一级淫片aaaaaaaaa | 狠狠插狠狠操 | 国产成人啪免费观看软件 | 蜜桃视频在线观看www社区 | 91在线第一页 | 亚洲成av人影片在线观看 | 久久久精品影院 | 国产高清一二三区 | 欧美区在线观看 | 中文字字幕一区二区三区四区五区 | 国产精品一区二区欧美黑人喷潮水 | 亚洲欧美日韩久久 | 紧缚调教一区二区三区视频 | 免费看欧美一级片 | 欧美日韩国产高清 | 91精品久久久久久久久中文字幕 | 综合久久国产 | 国产二区三区 | a级片网站 | 殴美成人在线视频 | 日韩免费电影 | 久久久女女女女999久久 | 久久久精品网 | 狠狠综合久久av一区二区小说 | 久久精品亚洲一区二区三区浴池 | h视频在线免费观看 | 澳门永久av免费网站 | 亚洲精品视频免费观看 | 第四色影音先锋 | 99国产精品久久久 | 国产精品中文字幕一区二区三区 | 欧州一区| 亚洲一区二区三区高清 | 亚洲免费影院 | 国产片侵犯亲女视频播放 | 农村真人裸体丰满少妇毛片 | 91免费观看国产 | 欧美一级在线视频 | 国产精品中文字幕一区二区三区 | 国产yw851.c免费观看网站 |