嵌入式 Web 伺服器

每個 Spring Boot Web 應用程式都包含一個嵌入式 Web 伺服器。此功能引發許多操作指南問題,包括如何變更嵌入式伺服器以及如何組態嵌入式伺服器。本節回答這些問題。

使用其他 Web 伺服器

許多 Spring Boot Starter 包含預設的嵌入式容器。

  • 對於 Servlet 堆疊應用程式,spring-boot-starter-web 透過包含 spring-boot-starter-tomcat 來包含 Tomcat,但您可以使用 spring-boot-starter-jettyspring-boot-starter-undertow 來替代。

  • 對於反應式堆疊應用程式,spring-boot-starter-webflux 透過包含 spring-boot-starter-reactor-netty 來包含 Reactor Netty,但您可以使用 spring-boot-starter-tomcatspring-boot-starter-jettyspring-boot-starter-undertow 來替代。

當切換到不同的 HTTP 伺服器時,您需要將預設的依賴項替換為您需要的依賴項。為了幫助您完成此過程,Spring Boot 為每個支援的 HTTP 伺服器提供了一個獨立的 Starter。

以下 Maven 範例展示如何排除 Tomcat 並包含 Jetty 以用於 Spring MVC

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-web</artifactId>
	<exclusions>
		<!-- Exclude the Tomcat dependency -->
		<exclusion>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-tomcat</artifactId>
		</exclusion>
	</exclusions>
</dependency>
<!-- Use Jetty instead -->
<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-jetty</artifactId>
</dependency>

以下 Gradle 範例組態必要的依賴項和 模組替換,以在 Spring WebFlux 中使用 Undertow 取代 Reactor Netty

dependencies {
	implementation "org.springframework.boot:spring-boot-starter-undertow"
	implementation "org.springframework.boot:spring-boot-starter-webflux"
	modules {
		module("org.springframework.boot:spring-boot-starter-reactor-netty") {
			replacedBy("org.springframework.boot:spring-boot-starter-undertow", "Use Undertow instead of Reactor Netty")
		}
	}
}
使用 WebClient 類別需要 spring-boot-starter-reactor-netty,因此即使您需要包含不同的 HTTP 伺服器,您也可能需要保留對 Netty 的依賴。

停用 Web 伺服器

如果您的類別路徑包含啟動 Web 伺服器所需的位元,Spring Boot 將自動啟動它。若要停用此行為,請在您的 application.properties 中組態 WebApplicationType,如下列範例所示

  • 屬性

  • YAML

spring.main.web-application-type=none
spring:
  main:
    web-application-type: "none"

變更 HTTP Port

在獨立應用程式中,主要的 HTTP Port 預設為 8080,但可以使用 server.port (例如,在 application.properties 中或作為系統屬性) 進行設定。由於 Environment 值的寬鬆綁定,您也可以使用 SERVER_PORT (例如,作為 OS 環境變數)。

若要完全關閉 HTTP 端點,但仍建立 WebApplicationContext,請使用 server.port=-1 (這樣做有時對於測試很有用)。

如需更多詳細資訊,請參閱 ‘Spring Boot Features’ 區段中的 自訂嵌入式 Servlet 容器,或 ServerProperties 類別。

使用隨機未指派的 HTTP Port

若要掃描可用 Port (使用 OS 原生方法以防止衝突),請使用 server.port=0

在執行階段探索 HTTP Port

您可以從記錄輸出或從 WebServerApplicationContext 透過其 WebServer 存取伺服器正在執行的 Port。取得該 Port 並確保已初始化的最佳方法是新增類型為 ApplicationListener<WebServerInitializedEvent>@Bean,並在發布事件時從事件中拉出容器。

使用 @SpringBootTest(webEnvironment=WebEnvironment.RANDOM_PORT) 的測試也可以使用 @LocalServerPort 註解將實際 Port 注入到欄位中,如下列範例所示

  • Java

  • Kotlin

import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
import org.springframework.boot.test.web.server.LocalServerPort;

@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
class MyWebIntegrationTests {

	@LocalServerPort
	int port;

	// ...

}
import org.springframework.boot.test.context.SpringBootTest
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment
import org.springframework.boot.test.web.server.LocalServerPort

@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
class MyWebIntegrationTests {

	@LocalServerPort
	var port = 0

	// ...

}

@LocalServerPort@Value("${local.server.port}") 的元註解。請勿嘗試在常規應用程式中注入 Port。正如我們剛才看到的,該值僅在容器初始化後設定。與測試相反,應用程式程式碼回呼會提前處理 (在值實際可用之前)。

啟用 HTTP 回應壓縮

Jetty、Tomcat、Reactor Netty 和 Undertow 支援 HTTP 回應壓縮。可以在 application.properties 中啟用它,如下所示

  • 屬性

  • YAML

server.compression.enabled=true
server:
  compression:
    enabled: true

預設情況下,回應長度必須至少為 2048 位元組才能執行壓縮。您可以透過設定 server.compression.min-response-size 屬性來組態此行為。

預設情況下,僅當回應的內容類型為下列其中一種時,才會壓縮回應

  • text/html

  • text/xml

  • text/plain

  • text/css

  • text/javascript

  • application/javascript

  • application/json

  • application/xml

您可以透過設定 server.compression.mime-types 屬性來組態此行為。

組態 SSL

可以透過設定各種 server.ssl.* 屬性以宣告方式組態 SSL,通常在 application.propertiesapplication.yaml 中。請參閱 Ssl 以取得所有支援屬性的詳細資訊。

下列範例顯示使用 Java KeyStore 檔案設定 SSL 屬性

  • 屬性

  • YAML

server.port=8443
server.ssl.key-store=classpath:keystore.jks
server.ssl.key-store-password=secret
server.ssl.key-password=another-secret
server:
  port: 8443
  ssl:
    key-store: "classpath:keystore.jks"
    key-store-password: "secret"
    key-password: "another-secret"

使用如前述範例的組態表示應用程式不再支援 Port 8080 上的純 HTTP 連接器。Spring Boot 不支援透過 application.properties 組態 HTTP 連接器和 HTTPS 連接器兩者。如果您想要兩者都有,您需要以程式設計方式組態其中一個。我們建議使用 application.properties 來組態 HTTPS,因為 HTTP 連接器是兩者中較容易以程式設計方式組態的連接器。

使用 PEM 編碼檔案

您可以使用 PEM 編碼檔案來替代 Java KeyStore 檔案。您應盡可能使用 PKCS#8 金鑰檔案。PEM 編碼的 PKCS#8 金鑰檔案以 -----BEGIN PRIVATE KEY----------BEGIN ENCRYPTED PRIVATE KEY----- 標頭開頭。

如果您有其他格式的檔案,例如 PKCS#1 (-----BEGIN RSA PRIVATE KEY-----) 或 SEC 1 (-----BEGIN EC PRIVATE KEY-----),您可以使用 OpenSSL 將它們轉換為 PKCS#8

openssl pkcs8 -topk8 -nocrypt -in <input file> -out <output file>

下列範例顯示使用 PEM 編碼憑證和私密金鑰檔案設定 SSL 屬性

  • 屬性

  • YAML

server.port=8443
server.ssl.certificate=classpath:my-cert.crt
server.ssl.certificate-private-key=classpath:my-cert.key
server.ssl.trust-certificate=classpath:ca-cert.crt
server:
  port: 8443
  ssl:
    certificate: "classpath:my-cert.crt"
    certificate-private-key: "classpath:my-cert.key"
    trust-certificate: "classpath:ca-cert.crt"

使用 SSL Bundle

或者,可以在 SSL bundle 中組態 SSL 信任材料,並將其套用於 Web 伺服器,如此範例所示

  • 屬性

  • YAML

server.port=8443
server.ssl.bundle=example
server:
  port: 8443
  ssl:
    bundle: "example"
server.ssl.bundle 屬性不能與 server.ssl 下的離散 Java KeyStore 或 PEM 屬性選項結合使用。

組態伺服器名稱指示

可以將 Tomcat、Netty 和 Undertow 組態為針對個別主機名稱使用唯一的 SSL 信任材料,以支援伺服器名稱指示 (SNI)。Jetty 不支援 SNI 組態,但如果向 Jetty 提供多個憑證,Jetty 可以自動設定 SNI

假設已組態名為 webweb-alt1web-alt2SSL bundle,則可以使用下列組態將每個 bundle 指派給嵌入式 Web 伺服器服務的主機名稱

  • 屬性

  • YAML

server.port=8443
server.ssl.bundle=web
server.ssl.server-name-bundles[0].server-name=alt1.example.com
server.ssl.server-name-bundles[0].bundle=web-alt1
server.ssl.server-name-bundles[1].server-name=alt2.example.com
server.ssl.server-name-bundles[1].bundle=web-alt2
server:
  port: 8443
  ssl:
    bundle: "web"
    server-name-bundles:
      - server-name: "alt1.example.com"
        bundle: "web-alt1"
      - server-name: "alt2.example.com"
        bundle: "web-alt2"

使用 server.ssl.bundle 指定的 bundle 將用於預設主機,以及任何不支援 SNI 的用戶端。如果已組態任何 server.ssl.server-name-bundles,則必須組態此預設 bundle。

組態 HTTP/2

您可以使用 server.http2.enabled 組態屬性在您的 Spring Boot 應用程式中啟用 HTTP/2 支援。h2 (透過 TLS 的 HTTP/2) 和 h2c (透過 TCP 的 HTTP/2) 都受到支援。若要使用 h2,也必須啟用 SSL。當未啟用 SSL 時,將使用 h2c。例如,當您的應用程式 在執行 TLS 終止的 Proxy 伺服器後方執行 時,您可能想要使用 h2c

Tomcat 的 HTTP/2

Spring Boot 預設隨附 Tomcat 10.1.x,該版本開箱即用支援 h2ch2。或者,如果程式庫及其依賴項安裝在主機作業系統上,您可以將 libtcnative 用於 h2 支援。

如果尚未提供程式庫目錄,則必須將其提供給 JVM 程式庫路徑。您可以使用 JVM 引數 (例如 -Djava.library.path=/usr/local/opt/tomcat-native/lib) 來執行此操作。如需更多資訊,請參閱 官方 Tomcat 文件

Jetty 的 HTTP/2

為了支援 HTTP/2,Jetty 需要額外的 org.eclipse.jetty.http2:jetty-http2-server 依賴項。若要使用 h2c,則不需要其他依賴項。若要使用 h2,您還需要選擇下列其中一個依賴項,具體取決於您的部署

  • org.eclipse.jetty:jetty-alpn-java-server 以使用 JDK 內建支援

  • org.eclipse.jetty:jetty-alpn-conscrypt-serverConscrypt 程式庫

Reactor Netty 的 HTTP/2

spring-boot-webflux-starter 預設使用 Reactor Netty 作為伺服器。Reactor Netty 開箱即用支援 h2ch2。為了獲得最佳執行階段效能,此伺服器也支援使用原生程式庫的 h2。若要啟用此功能,您的應用程式需要額外的依賴項。

Spring Boot 管理 io.netty:netty-tcnative-boringssl-static "uber jar" 的版本,其中包含所有平台的原生程式庫。開發人員可以選擇僅匯入使用分類器的必要依賴項 (請參閱 Netty 官方文件)。

Undertow 的 HTTP/2

Undertow 開箱即用支援 h2ch2

組態 Web 伺服器

通常,您應首先考慮使用許多可用的組態金鑰之一,並透過在您的 application.propertiesapplication.yaml 檔案中新增新項目來自訂您的 Web 伺服器。請參閱 探索外部屬性的內建選項)。server.* 命名空間在此非常有用,它包含例如 server.tomcat.*server.jetty.* 和其他伺服器特定功能的命名空間。請參閱 常用應用程式屬性 列表。

先前的章節已涵蓋許多常見的使用案例,例如壓縮、SSL 或 HTTP/2。但是,如果您的使用案例不存在組態金鑰,則您應查看 WebServerFactoryCustomizer。您可以宣告此類元件並存取與您的選擇相關的伺服器 Factory:您應針對選定的伺服器 (Tomcat、Jetty、Reactor Netty、Undertow) 和選定的 Web 堆疊 (Servlet 或反應式) 選擇變體。

以下範例適用於搭配 spring-boot-starter-web (Servlet 堆疊) 的 Tomcat

  • Java

  • Kotlin

import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
import org.springframework.stereotype.Component;

@Component
public class MyTomcatWebServerCustomizer implements WebServerFactoryCustomizer<TomcatServletWebServerFactory> {

	@Override
	public void customize(TomcatServletWebServerFactory factory) {
		// customize the factory here
	}

}
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory
import org.springframework.boot.web.server.WebServerFactoryCustomizer
import org.springframework.stereotype.Component

@Component
class MyTomcatWebServerCustomizer : WebServerFactoryCustomizer<TomcatServletWebServerFactory?> {

	override fun customize(factory: TomcatServletWebServerFactory?) {
		// customize the factory here
	}

}
Spring Boot 在內部使用該基礎架構來自動組態伺服器。自動組態的 WebServerFactoryCustomizer Bean 的順序為 0,並且會在任何使用者定義的自訂工具之前處理,除非它具有明確指示的其他順序。

一旦您使用自訂工具存取 WebServerFactory,您就可以使用它來組態特定部分,例如連接器、伺服器資源或伺服器本身 - 全部使用伺服器特定的 API。

此外,Spring Boot 還提供

伺服器 Servlet 堆疊 反應式堆疊

Tomcat

TomcatServletWebServerFactory

TomcatReactiveWebServerFactory

Jetty

JettyServletWebServerFactory

JettyReactiveWebServerFactory

Undertow

UndertowServletWebServerFactory

UndertowReactiveWebServerFactory

Reactor

N/A

NettyReactiveWebServerFactory

作為最後手段,您也可以宣告您自己的 WebServerFactory Bean,它將覆寫 Spring Boot 提供的 Bean。當您這樣做時,自動組態的自訂工具仍會套用於您的自訂 Factory,因此請謹慎使用該選項。

將 Servlet、Filter 或 Listener 新增到應用程式

在 Servlet 堆疊應用程式中,也就是使用 spring-boot-starter-web,有兩種方法可以將 ServletFilterServletContextListener 和 Servlet API 支援的其他 Listener 新增到您的應用程式

透過使用 Spring Bean 新增 Servlet、Filter 或 Listener

若要透過使用 Spring Bean 新增 ServletFilter 或 Servlet *Listener,您必須為其提供 @Bean 定義。當您想要注入組態或依賴項時,這樣做非常有用。但是,您必須非常小心,它們不會導致過多其他 Bean 的急切初始化,因為它們必須在應用程式生命週期的早期安裝在容器中。(例如,讓它們依賴您的 DataSource 或 JPA 組態不是一個好主意。) 您可以透過在首次使用時而不是在初始化時延遲初始化 Bean 來解決此類限制。

在 Filter 和 Servlet 的情況下,您也可以透過新增 FilterRegistrationBeanServletRegistrationBean 來替代或補充底層元件,從而新增映射和初始化參數。

如果在 Filter 註冊上未指定 dispatcherType,則會使用 REQUEST。這與 Servlet 規格的預設分派器類型一致。

與任何其他 Spring Bean 一樣,您可以定義 Servlet Filter Bean 的順序;請務必查看 將 Servlet、Filter 和 Listener 註冊為 Spring Bean 區段。

停用 Servlet 或 Filter 的註冊

先前所述,任何 ServletFilter Bean 都會自動向 Servlet 容器註冊。若要停用特定 FilterServlet Bean 的註冊,請為其建立註冊 Bean 並將其標記為已停用,如下列範例所示

  • Java

  • Kotlin

import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration(proxyBeanMethods = false)
public class MyFilterConfiguration {

	@Bean
	public FilterRegistrationBean<MyFilter> registration(MyFilter filter) {
		FilterRegistrationBean<MyFilter> registration = new FilterRegistrationBean<>(filter);
		registration.setEnabled(false);
		return registration;
	}

}
import org.springframework.boot.web.servlet.FilterRegistrationBean
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration

@Configuration(proxyBeanMethods = false)
class MyFilterConfiguration {

	@Bean
	fun registration(filter: MyFilter): FilterRegistrationBean<MyFilter> {
		val registration = FilterRegistrationBean(filter)
		registration.isEnabled = false
		return registration
	}

}

透過使用類別路徑掃描新增 Servlet、Filter 和 Listener

透過使用 @ServletComponentScan 註解 @Configuration 類別並指定包含您要註冊元件的套件,可以自動向嵌入式 Servlet 容器註冊 @WebServlet@WebFilter@WebListener 註解類別。預設情況下,@ServletComponentScan 從註解類別的套件掃描。

組態存取記錄

可以透過其各自的命名空間為 Tomcat、Undertow 和 Jetty 組態存取記錄。

例如,下列設定使用 自訂模式 在 Tomcat 上記錄存取。

  • 屬性

  • YAML

server.tomcat.basedir=my-tomcat
server.tomcat.accesslog.enabled=true
server.tomcat.accesslog.pattern=%t %a %r %s (%D microseconds)
server:
  tomcat:
    basedir: "my-tomcat"
    accesslog:
      enabled: true
      pattern: "%t %a %r %s (%D microseconds)"
記錄的預設位置是相對於 Tomcat 基底目錄的 logs 目錄。預設情況下,logs 目錄是一個臨時目錄,因此您可能想要修正 Tomcat 的基底目錄或使用記錄的絕對路徑。在先前的範例中,記錄在相對於應用程式工作目錄的 my-tomcat/logs 中可用。

可以類似的方式組態 Undertow 的存取記錄,如下列範例所示

  • 屬性

  • YAML

server.undertow.accesslog.enabled=true
server.undertow.accesslog.pattern=%t %a %r %s (%D milliseconds)
server.undertow.options.server.record-request-start-time=true
server:
  undertow:
    accesslog:
      enabled: true
      pattern: "%t %a %r %s (%D milliseconds)"
    options:
      server:
        record-request-start-time: true

請注意,除了啟用存取記錄和組態其模式之外,還啟用了記錄請求開始時間。當在存取記錄模式中包含回應時間 (%D) 時,這是必要的。記錄儲存在相對於應用程式工作目錄的 logs 目錄中。您可以透過設定 server.undertow.accesslog.dir 屬性來自訂此位置。

最後,也可以如下組態 Jetty 的存取記錄

  • 屬性

  • YAML

server.jetty.accesslog.enabled=true
server.jetty.accesslog.filename=/var/log/jetty-access.log
server:
  jetty:
    accesslog:
      enabled: true
      filename: "/var/log/jetty-access.log"

預設情況下,記錄會重新導向到 System.err。如需更多詳細資訊,請參閱 Jetty 文件。

在前端 Proxy 伺服器後方執行

如果您的應用程式在 Proxy、負載平衡器或雲端中執行,則請求資訊 (例如主機、Port、Scheme...​) 可能會沿途變更。您的應用程式可能在 10.10.10.10:8080 上執行,但 HTTP 用戶端應僅看到 example.org

RFC7239 "Forwarded Headers" 定義了 Forwarded HTTP 標頭;Proxy 可以使用此標頭來提供有關原始請求的資訊。您可以組態您的應用程式以讀取這些標頭,並在建立連結並在 HTTP 302 回應、JSON 文件或 HTML 頁面中將它們傳送給用戶端時自動使用該資訊。還有非標準標頭,例如 X-Forwarded-HostX-Forwarded-PortX-Forwarded-ProtoX-Forwarded-SslX-Forwarded-Prefix

如果 Proxy 新增常用的 X-Forwarded-ForX-Forwarded-Proto 標頭,則將 server.forward-headers-strategy 設定為 NATIVE 就足以支援這些標頭。使用此選項,Web 伺服器本身原生支援此功能;您可以查看其特定文件以了解特定行為。

如果這還不夠,Spring Framework 為 Servlet 堆疊提供了 ForwardedHeaderFilter,為反應式堆疊提供了 ForwardedHeaderTransformer。您可以透過將 server.forward-headers-strategy 設定為 FRAMEWORK 在您的應用程式中使用它們。

如果您正在使用 Tomcat 並在 Proxy 終止 SSL,則應將 server.tomcat.redirect-context-root 設定為 false。這允許在執行任何重新導向之前先採用 X-Forwarded-Proto 標頭。
如果您的應用程式在 支援的雲端平台中 執行,則 server.forward-headers-strategy 屬性預設為 NATIVE。在所有其他情況下,它預設為 NONE

自訂 Tomcat 的 Proxy 組態

如果您使用 Tomcat,您可以額外設定用於攜帶「轉發」資訊的標頭名稱,如下列範例所示

  • 屬性

  • YAML

server.tomcat.remoteip.remote-ip-header=x-your-remote-ip-header
server.tomcat.remoteip.protocol-header=x-your-protocol-header
server:
  tomcat:
    remoteip:
      remote-ip-header: "x-your-remote-ip-header"
      protocol-header: "x-your-protocol-header"

Tomcat 也配置了一個正則表達式,用於匹配要信任的內部代理。有關預設值,請參閱附錄中的 server.tomcat.remoteip.internal-proxies 條目。您可以透過在 application.properties 中新增條目來自訂閥門的配置,如下列範例所示

  • 屬性

  • YAML

server.tomcat.remoteip.internal-proxies=192\.168\.\d{1,3}\.\d{1,3}
server:
  tomcat:
    remoteip:
      internal-proxies: "192\\.168\\.\\d{1,3}\\.\\d{1,3}"
您可以將 internal-proxies 設定為空來信任所有代理(但請勿在生產環境中這樣做)。

您可以完全控制 Tomcat 的 RemoteIpValve 配置,方法是關閉自動配置(為此,請設定 server.forward-headers-strategy=NONE)並使用 WebServerFactoryCustomizer Bean 新增一個新的閥門實例。

啟用 Tomcat 的多個連接器

您可以將 org.apache.catalina.connector.Connector 新增至 TomcatServletWebServerFactory,這可以允許多個連接器,包括 HTTP 和 HTTPS 連接器,如下列範例所示

  • Java

  • Kotlin

import org.apache.catalina.connector.Connector;

import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration(proxyBeanMethods = false)
public class MyTomcatConfiguration {

	@Bean
	public WebServerFactoryCustomizer<TomcatServletWebServerFactory> connectorCustomizer() {
		return (tomcat) -> tomcat.addAdditionalTomcatConnectors(createConnector());
	}

	private Connector createConnector() {
		Connector connector = new Connector("org.apache.coyote.http11.Http11NioProtocol");
		connector.setPort(8081);
		return connector;
	}

}
import org.apache.catalina.connector.Connector
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory
import org.springframework.boot.web.server.WebServerFactoryCustomizer
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration

@Configuration(proxyBeanMethods = false)
class MyTomcatConfiguration {

	@Bean
	fun connectorCustomizer(): WebServerFactoryCustomizer<TomcatServletWebServerFactory> {
		return WebServerFactoryCustomizer { tomcat: TomcatServletWebServerFactory ->
			tomcat.addAdditionalTomcatConnectors(
				createConnector()
			)
		}
	}

	private fun createConnector(): Connector {
		val connector = Connector("org.apache.coyote.http11.Http11NioProtocol")
		connector.port = 8081
		return connector
	}

}

啟用 Tomcat 的 MBean 登錄

內嵌 Tomcat 的 MBean 登錄預設為停用。這可以最大限度地減少 Tomcat 的記憶體佔用量。如果您想使用 Tomcat 的 MBean,例如為了讓 Micrometer 可以使用它們來公開指標,則必須使用 server.tomcat.mbeanregistry.enabled 屬性來執行此操作,如下列範例所示

  • 屬性

  • YAML

server.tomcat.mbeanregistry.enabled=true
server:
  tomcat:
    mbeanregistry:
      enabled: true

啟用 Undertow 的多個監聽器

UndertowBuilderCustomizer 新增至 UndertowServletWebServerFactory,並將監聽器新增至 Builder,如下列範例所示

  • Java

  • Kotlin

import io.undertow.Undertow.Builder;

import org.springframework.boot.web.embedded.undertow.UndertowServletWebServerFactory;
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration(proxyBeanMethods = false)
public class MyUndertowConfiguration {

	@Bean
	public WebServerFactoryCustomizer<UndertowServletWebServerFactory> undertowListenerCustomizer() {
		return (factory) -> factory.addBuilderCustomizers(this::addHttpListener);
	}

	private Builder addHttpListener(Builder builder) {
		return builder.addHttpListener(8080, "0.0.0.0");
	}

}
import io.undertow.Undertow
import org.springframework.boot.web.embedded.undertow.UndertowBuilderCustomizer
import org.springframework.boot.web.embedded.undertow.UndertowServletWebServerFactory
import org.springframework.boot.web.server.WebServerFactoryCustomizer
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration

@Configuration(proxyBeanMethods = false)
class MyUndertowConfiguration {

	@Bean
	fun undertowListenerCustomizer(): WebServerFactoryCustomizer<UndertowServletWebServerFactory> {
		return WebServerFactoryCustomizer { factory: UndertowServletWebServerFactory ->
			factory.addBuilderCustomizers(
				UndertowBuilderCustomizer { builder: Undertow.Builder -> addHttpListener(builder) })
		}
	}

	private fun addHttpListener(builder: Undertow.Builder): Undertow.Builder {
		return builder.addHttpListener(8080, "0.0.0.0")
	}

}

使用 @ServerEndpoint 建立 WebSocket 端點

如果您想在使用嵌入式容器的 Spring Boot 應用程式中使用 @ServerEndpoint,則必須宣告單個 ServerEndpointExporter @Bean,如下列範例所示

  • Java

  • Kotlin

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;

@Configuration(proxyBeanMethods = false)
public class MyWebSocketConfiguration {

	@Bean
	public ServerEndpointExporter serverEndpointExporter() {
		return new ServerEndpointExporter();
	}

}
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import org.springframework.web.socket.server.standard.ServerEndpointExporter

@Configuration(proxyBeanMethods = false)
class MyWebSocketConfiguration {

	@Bean
	fun serverEndpointExporter(): ServerEndpointExporter {
		return ServerEndpointExporter()
	}

}

前述範例中顯示的 Bean 會將任何 @ServerEndpoint 註釋的 Bean 註冊到基礎 WebSocket 容器。當部署到獨立 Servlet 容器時,此角色由 Servlet 容器初始化器執行,並且不需要 ServerEndpointExporter Bean。