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

深度解析SpringBoot內(nèi)嵌Web容器

 更新時間:2023年06月27日 08:41:14   作者:劉牌  
這篇文章主要給大家介紹SpringBoot的內(nèi)嵌Web容器,SpringBoot將Web容器進(jìn)行了內(nèi)嵌,我們只需要將項(xiàng)目打成一個jar包,就可以運(yùn)行了,大大省略了開發(fā)成本,那么SpringBoot是怎么實(shí)現(xiàn)的呢,我們今天就來詳細(xì)介紹

SpringBoot提供的內(nèi)嵌容器

SpringBoot提供了四種Web容器,分別為Tomcat,Jetty,Undertow,Netty。

Tomcat

Spring Boot 默認(rèn)使用 Tomcat 作為嵌入式 Web 容器。Tomcat 作為一個流行的 Web 容器,容易能夠理解、配置和管理??梢酝ㄟ^使用spring-boot-starter-web來啟用 Tomcat 容器。

Jetty

Jetty 同樣是一個流行的嵌入式 Web 容器,它的缺省配置相對精簡,從而有利快速啟動。可以通過使用spring-boot-starter-jetty來啟用 Jetty 容器。

Undertow

Undertow 是一個由 JBoss 開發(fā)的輕量級的嵌入式 Web 服務(wù)器。它具有出色的性能和低資源占用率,是一個適合微服務(wù)實(shí)現(xiàn)的 Web 服務(wù)器??梢允褂胹pring-boot-starter-undertow來啟用 Undertow 容器。

Netty

Netty是一個高性能的網(wǎng)絡(luò)框架,需要引入spring-boot-starter-webflux和spring-boot-starter-reactor-netty來開啟Netty作為Web容器。

使用

因?yàn)镾pringBoot默認(rèn)的是Tomcat作為Web容器,如果我們需要使用使用其他Web容器,那么需要排除Tomcat容器,再引入其他容器,Tomcat容器位于spring-boot-starter-web模塊下,所以我們需要在maven的pom.xml中移除Tomcat,如下。

<dependency>
??????<groupId>org.springframework.boot</groupId>
??????<artifactId>spring-boot-starter-web</artifactId>
??????<version>3.0.2</version>
??????<exclusions>
??????????<exclusion>
??????????????<groupId>org.springframework.boot</groupId>
??????????????<artifactId>spring-boot-starter-tomcat</artifactId>
??????????</exclusion>
??????</exclusions>
</dependency>

然后引入對應(yīng)的Web容器,比如引入Undertow

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

然后可以在yml文件中配置相應(yīng)容器的參數(shù),如下配置undertow.

server:
??port:?8080
??undertow:
????threads:
??????worker:?10
??????io:?10
????direct-buffers:?true

其他web容器可以根據(jù)實(shí)際情況配置,從ServerProperties配置文件中可以查看對應(yīng)的Web容器的相關(guān)配置。

源碼解析

下面從源碼進(jìn)行分析,我們先使用SpringBoot的默認(rèn)Web容器Tomcat進(jìn)行分析。

那么源碼應(yīng)該從哪里看起呢,對于SpringBoot這么龐大復(fù)雜的項(xiàng)目,首先,我們在使用SpringBoot的時候,需要在application.yml文件中配置相關(guān)信息,比如端口,如果不配置端口,默認(rèn)是8080,那么這個端口肯定是web容器的端口,如果是Tomcat,那么Tomcat就設(shè)置為這個端口,Undertow也是,依此類推。

那么這里就是一個入口,在SpringBoot中,我們要獲取yml文件中的配置信息,一般是通過@ConfigurationProperties注解,我們可以按住ctrl,然后鼠標(biāo)點(diǎn)擊這個port,就能跳到對應(yīng)的屬性類里面。

屬性類ServerProperties就是專門獲取yml文件中的配置,然后以供使用。

到了屬性類里面后,我們繼續(xù)ctrl,然后會彈出很多類,如下所示。

因?yàn)槲覀兪褂玫氖荰omcat,那么就選擇一個Tomcat相關(guān)的類,我們選擇TomcatWebServerFactoryCustomizer,這個類實(shí)現(xiàn)了接口WebServerFactoryCustomizer,并實(shí)現(xiàn)了方法customize。

customize的參數(shù)是ConfigurableTomcatWebServerFactory,它是一個接口,它還繼承了接口ConfigurableWebServerFactory,我們從ConfigurableWebServerFactory中看出里面有設(shè)置端口,地址等方法。

我們再回頭看ConfigurableTomcatWebServerFactory,可以看出里面是一些Tomcat相關(guān)的方法。

然后繼續(xù)看ConfigurableUndertowWebServerFactory,可以看出里面是對Undertow的一些屬性設(shè)置的方法。

我們回到TomcatWebServerFactoryCustomizer類中,SpringBoot使用了它的PropertyMapper類對屬性進(jìn)行設(shè)置,我們可以看出它使用propertyMapper.from().to()語法,其實(shí)就是將ServerProperties中的屬性設(shè)置到ConfigurableTomcatWebServerFactory中,這個屬性設(shè)置是在Spring對Bean進(jìn)行初始化時候設(shè)置的,使用的是Spring的后置處理器來實(shí)現(xiàn)的,后面我們繼續(xù)說。

然后我們繼續(xù)看一下TomcatWebServerFactoryCustomizer,他有一個構(gòu)造函數(shù),參數(shù)是Environment和ServerProperties,那么就證明其他地方對其進(jìn)行了new操作。

我們也是用ctrl套路,點(diǎn)擊構(gòu)造函數(shù)后跳到了EmbeddedWebServerFactoryCustomizerAutoConfiguration自動裝配類中,這個類中有四個靜態(tài)類,我們可以看出,他們的作用都是創(chuàng)建對應(yīng)的定制器Bean,其實(shí)就是將yml文件中的Web容器配置進(jìn)行裝配,以供后面使用。

上面說的這一堆其實(shí)就是SpringBoot的自動裝配,其目的就是創(chuàng)建對應(yīng)的Customizer,因?yàn)槊總€Web容器的配置項(xiàng)不一樣,所以就需要不同的Customizer和Factory。

上面說了這么多,怎么感覺和源碼沒關(guān)系呢,沒錯,其實(shí)上面說的并不是核心源碼,那么怎么找到核心源碼呢?我們思考一下,既然上面是部分源碼,那么源碼肯定會執(zhí)行到這里。

查看調(diào)用鏈

我們在上面的TomcatWebServerFactoryCustomizer類中的customize方法中打一個斷點(diǎn),然后debug,于是得到調(diào)用鏈如下。

我們可以看出會調(diào)用onRefresh()方法,因?yàn)?code>AbstractApplicationContext使用的是模板方法模式,具體的實(shí)現(xiàn)交給子類實(shí)現(xiàn),因?yàn)槭褂玫氖荰omcat,所以交給了ServletWebServerApplicationContext類來實(shí)現(xiàn),具體的子類里面有一個createWebServer()方法,它就是創(chuàng)建Web容器。

具體實(shí)現(xiàn)如下,如下是Tomcat的實(shí)現(xiàn),里面會涉及到兩個重要的接口WebServerWebServerFactory

WebServer

WebServer是容器的頂層接口,具體實(shí)現(xiàn)交給具體的容器實(shí)現(xiàn)類,如Tomcat則使用TomcatWebServer,Undertow則使用UndertowWebServer,Jetty,Netty也是如此。

此接口提供了一些方法,start()啟動Web服務(wù)器,stop()停止Web服務(wù)器,getPort()獲取服務(wù)器端口。

不過對于start()和stop(),它們只是接口抽象的規(guī)范,在具體的實(shí)現(xiàn)中,也并不是全部都按照這個標(biāo)準(zhǔn),start()方法上有備注Starts the web server. Calling this method on an already started server has no effect.,翻譯為:啟動web服務(wù)器。在已啟動的服務(wù)器上調(diào)用此方法無效。,比如Tomcat的就沒有在start()方法中啟動服務(wù)器,具體我們等會會看。

WebServerFactory

WebServerFactory是一個接口,沒有定義任何方法,它就創(chuàng)建Web服務(wù)器的工廠的標(biāo)記接口,Spring中很多地方也是這樣的風(fēng)格。

這個接口重要的兩個子接口,也是我們需要關(guān)注的兩個子接口分別是ServletWebServerFactoryReactiveWebServerFactory,它們兩個都定義了一個方法getWebServer

Jetty,Undertow,Tomcat三個都屬于Servlet容器,所以使用的是ServletWebServerFactory來創(chuàng)建Web容器。

Netty不是Servlet容器,所以使用的是ReactiveWebServerFactory來創(chuàng)建Web容器。

上面對這兩個接口進(jìn)行了介紹,基本上整個Web容器都是圍繞這兩個接口來,我們下面繼續(xù)分析。

獲取WebServerFactory

首先我們要先獲取web服務(wù)的工廠類的Bean,才能創(chuàng)建Web容器,因?yàn)槲覀兪褂玫氖荰omcat,所以獲取到的工廠類是TomcatServletWebServerFactory,具體的獲取Bean的過程我們就沒有必要去一一說明,只要對Spring IOC稍微熟悉一點(diǎn)就能理解,我們主要說一下在后置處理器。

上面我們介紹了Tomcat容器的定制器Customizer,里面對Web容器的配置屬性進(jìn)行組裝,它就是發(fā)生在Bean的初始化前,用到的Bean后置處理器是WebServerFactoryCustomizerBeanPostProcessor。

Bean的后置處理器中,會調(diào)用對應(yīng)的定制器,Tomcat調(diào)用的就是TomcatWebServerFactoryCustomizer,其他的也一樣,其目的都是定制WebServerFactory。

經(jīng)過一系列處理后,就從IOC容器中獲取到了WebServerFactoryBean,然后再使用這個工廠去創(chuàng)建Web服務(wù)。

創(chuàng)建Web服務(wù)

獲取到WebServerFactory后,就可以創(chuàng)建Web容器,因?yàn)槭褂玫氖荰omcat,所以使用的是TomcatServletWebServerFactory,如下,我們就看到了Tomcat的身影。

最后啟動Tomcat容器是在TomcatWebServer中,在TomcatWebServer的構(gòu)造函數(shù)中調(diào)用initialize(),在initialize()中我們看是this.tomcat.start(),Tomcat被啟動了。

上面我們在說WebServer接口的時候,說了啟動start()方法,在Tomcat的實(shí)現(xiàn)中就沒有使用start()來啟動容器,但是在Undertow中,就使用了start()方法來啟動容器。

Undertow容器啟動

上面我們介紹了Tomcat容器的創(chuàng)建,Undertow的流程和Tomcat基本上是一樣的,但是在啟動的時候,Undertow是在start()方法中啟動,而start()方法需要在 finishRefresh()這一步中執(zhí)行。

在finishRefresh()中,會調(diào)用生命周期處理器

最終會走到WebServerStartStopLifecycle這個生命周期,這里就會調(diào)用WebServer中的start()方法。

最終在UndertowWebServer中啟動Undertow容器

具體執(zhí)行順序如下。

finishRefresh() -> getLifecycleProcessor().onRefresh() -> startBeans(true) -> start() -> doStart(this.lifecycleBeans, member.name, this.autoStartupOnly) -> bean.start() -> this.webServer.start()

上面我們分析了Tomcat和Undertow的創(chuàng)建流程,Jetty和Netty也是大同小異,因?yàn)镾pring使用了模板方法模式,具體的實(shí)現(xiàn)交給具體的Web容器,所以在整體結(jié)構(gòu)上是差不多的,只是實(shí)現(xiàn)方式不同。

總結(jié)

關(guān)于SpringBoot的內(nèi)嵌Web容器,就說得差不多了,我們從各種Web容器進(jìn)行介紹,包括他們的有點(diǎn),怎么在SpringBoot中使用,并對源碼進(jìn)行解析,在源碼解析這里,我們并沒有進(jìn)行芝麻細(xì)節(jié)式解析,而是從大體上進(jìn)行解析,只有對大致結(jié)構(gòu)了解,才能更好地進(jìn)行深度學(xué)習(xí)。

SpringBoot內(nèi)嵌容器涉及的知識點(diǎn)還是比較多,需要對Spring和SpringBoot有一定的了解才能更好地學(xué)習(xí)它,本文基于SpringBoot3.0進(jìn)行解析, SpringBoot3.0中,Servlet也是遵循Jakata EE規(guī)范。

以上就是深度解析SpringBoot內(nèi)嵌Web容器的詳細(xì)內(nèi)容,更多關(guān)于SpringBoot Web容器的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Spring boot+mybatis+thymeleaf 實(shí)現(xiàn)登錄注冊增刪改查功能的示例代碼

    Spring boot+mybatis+thymeleaf 實(shí)現(xiàn)登錄注冊增刪改查功能的示例代碼

    這篇文章主要介紹了Spring boot+mybatis+thymeleaf 實(shí)現(xiàn)登錄注冊增刪改查功能的示例代碼,本文通過實(shí)例圖文相結(jié)合給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-07-07
  • SpringBoot事件監(jiān)聽器@EventListener的實(shí)現(xiàn)

    SpringBoot事件監(jiān)聽器@EventListener的實(shí)現(xiàn)

    @EventListener注解用于處理應(yīng)用程序事件,提供了一種方便的方式來監(jiān)聽和響應(yīng)各種事件,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2024-11-11
  • Android實(shí)現(xiàn)兼容的水波紋效果

    Android實(shí)現(xiàn)兼容的水波紋效果

    Android的水波紋效果只有高版本才有,我們希望自己的應(yīng)用在低版本用低版本的陰影,而高版本用水波紋,這怎么做呢?下面一起來學(xué)習(xí)學(xué)習(xí)。
    2016-08-08
  • Java RateLimiter的限流詳解

    Java RateLimiter的限流詳解

    這篇文章主要為大家詳細(xì)介紹了Java RateLimiter的限流,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2022-03-03
  • 淺析Java中為什么要設(shè)計包裝類

    淺析Java中為什么要設(shè)計包裝類

    我們知道Java是一個面相對象的編程語言,基本類型并不具有對象的性質(zhì),為了讓基本類型也具有對象的特征,就出現(xiàn)了包裝類型,它相當(dāng)于將基本類型“包裝起來”,使得它具有了對象的性質(zhì),并且為其添加了屬性和方法,豐富了基本類型的操作
    2021-06-06
  • Maven項(xiàng)目中讀取src/main/resources目錄下的配置文件的方法

    Maven項(xiàng)目中讀取src/main/resources目錄下的配置文件的方法

    本篇文章主要介紹了Maven項(xiàng)目中讀取src/main/resources目錄下的配置文件的方法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-12-12
  • Java超詳細(xì)講解多態(tài)的調(diào)用

    Java超詳細(xì)講解多態(tài)的調(diào)用

    多態(tài)就是指程序中定義的引用變量所指向的具體類型和通過該引用變量發(fā)出的方法調(diào)用在編程時并不確定,而是在程序運(yùn)行期間才確定,即一個引用變量到底會指向哪個類的實(shí)例對象,該引用變量發(fā)出的方法調(diào)用到底是哪個類中實(shí)現(xiàn)的方法,必須在由程序運(yùn)行期間才能決定
    2022-05-05
  • Java訪問控制符原理及具體用法解析

    Java訪問控制符原理及具體用法解析

    這篇文章主要介紹了Java訪問控制符原理及具體用法解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2020-11-11
  • Java的深拷貝與淺拷貝的幾種實(shí)現(xiàn)方式

    Java的深拷貝與淺拷貝的幾種實(shí)現(xiàn)方式

    這篇文章主要介紹了Java的深拷貝與淺拷貝的幾種實(shí)現(xiàn)方式,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-01-01
  • 詳解SpringCloud-OpenFeign組件的使用

    詳解SpringCloud-OpenFeign組件的使用

    這篇文章主要介紹了SpringCloud-OpenFeign組件的使用,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-12-12

最新評論