|
此版本仍在开发中,尚未视为稳定版。如需最新稳定版本,请使用 Spring Boot 4.0.4! |
嵌入式 Web 服务器
每个 Spring Boot Web 应用程序都包含一个内嵌的 Web 服务器。 这一特性引发了许多“如何做”的问题,包括如何更换内嵌服务器以及如何配置内嵌服务器。 本节将回答这些问题。
使用其他 Web 服务器
许多 Spring Boot Starter 包含默认的嵌入式容器。
-
对于 Servlet 栈应用程序,
spring-boot-starter-web通过包含spring-boot-starter-tomcat来引入 Tomcat,但你也可以改用spring-boot-starter-jetty或spring-boot-starter-undertow。 -
对于响应式栈应用程序,
spring-boot-starter-webflux通过包含spring-boot-starter-reactor-netty来引入 Reactor Netty,但你也可以改用spring-boot-starter-tomcat、spring-boot-starter-jetty或spring-boot-starter-undertow。
切换到不同的 HTTP 服务器时,您需要将默认依赖项替换为您所需的依赖项。 为协助完成此过程,Spring Boot 为每个受支持的 HTTP 服务器都提供了单独的 starter。
以下 Maven 示例展示了如何在 Spring MVC 中排除 Tomcat 并引入 Jetty:
<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 示例配置了必要的依赖项和一个模块替换,以使用 Undertow 替代 Reactor Netty 作为 Spring WebFlux 的底层服务器:
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")
}
}
}
spring-boot-starter-reactor-netty 是使用 WebClient 类所必需的,因此即使您需要引入不同的 HTTP 服务器,也可能需要保留对 Netty 的依赖。 |
禁用 Web 服务器
如果您的类路径包含启动 Web 服务器所需的必要组件,Spring Boot 将自动启动它。
要禁用此行为,请在您的 application.properties 中配置 WebApplicationType,如下例所示:
-
Properties
-
YAML
spring.main.web-application-type=none
spring:
main:
web-application-type: "none"
更改 HTTP 端口
在独立应用程序中,主 HTTP 端口默认为 8080,但可以通过 server.port 进行设置(例如,在 application.properties 中或作为系统属性)。
得益于 Environment 值的宽松绑定,您也可以使用 SERVER_PORT(例如,作为操作系统环境变量)。
若要完全关闭 HTTP 端点但仍创建 WebApplicationContext,请使用 server.port=-1(这样做有时对测试很有用)。
更多详情,请参阅‘Spring Boot 特性’部分中的 自定义嵌入式 Servlet 容器,或 ServerProperties 类。
在运行时发现 HTTP 端口
您可以从日志输出中,或通过 WebServerApplicationContext 的 WebServer 访问服务器运行的端口。
获取该端口并确保其已初始化的最佳方法是添加一个类型为 ApplicationListener<WebServerInitializedEvent> 的 @Bean,并在事件发布时从中提取容器。
使用 @SpringBootTest(webEnvironment=WebEnvironment.RANDOM_PORT) 的测试也可以通过 @LocalServerPort 注解将实际端口注入到字段中,如下例所示:
-
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
// ...
}
|
|
启用 HTTP 响应压缩
HTTP 响应压缩由 Jetty、Tomcat、Reactor Netty 和 Undertow 支持。
可以在 application.properties 中启用,如下所示:
-
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
SSL 可以通过设置各种 server.ssl.* 属性以声明方式进行配置,通常是在 application.properties 或 application.yaml 中。
请参阅 Ssl 了解所有支持属性的详细信息。
以下示例展示了如何使用 Java KeyStore 文件设置 SSL 属性:
-
Properties
-
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"
使用如上例所示的配置意味着应用程序不再支持在 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 属性:
-
Properties
-
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 捆绑包
或者,可以将 SSL 信任材料配置在SSL 捆绑包中,并按照本示例所示应用到 Web 服务器:
-
Properties
-
YAML
server.port=8443
server.ssl.bundle=example
server:
port: 8443
ssl:
bundle: "example"
|
当使用 SSL 套件(bundle)时, |
配置服务器名称指示(SNI)
Tomcat、Netty 和 Undertow 可以配置为针对各个主机名使用独立的 SSL 信任材料,以支持服务器名称指示(SNI)。 Jetty 不支持 SNI 配置,但如果向 Jetty 提供多个证书,它可以自动设置 SNI。
假设已配置了名为 xref page、../reference/features/ssl.html 和 web 的SSL 证书包,则可以使用以下配置将每个证书包分配给嵌入式 Web 服务器所服务的主机名:
-
Properties
-
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 指定的证书包将用于默认主机,以及任何支持 SNI 的客户端。
如果配置了任意 server.ssl.server-name-bundles,则必须配置此默认证书包。
配置 HTTP/2
您可以通过 server.http2.enabled 配置属性在 Spring Boot 应用程序中启用 HTTP/2 支持。
同时支持 h2(基于 TLS 的 HTTP/2)和 h2c(基于 TCP 的 HTTP/2)。
要使用 h2,还必须启用 SSL。
当未启用 SSL 时,将使用 h2c。
例如,当您的应用程序运行在执行 TLS 终止的代理服务器之后时,您可能希望使用 #howto.webserver.use-behind-a-proxy-server。
使用 Tomcat 的 HTTP/2
Spring Boot 默认内置了 Tomcat 10.1.x,它开箱即用地支持 h2c 和 h2。
另外,如果在主机操作系统上安装了 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-server和 Conscrypt 库
使用 Reactor Netty 的 HTTP/2
spring-boot-webflux-starter 默认使用 Reactor Netty 作为服务器。
Reactor Netty 开箱即支持 h2c 和 h2。
为了获得最佳的运行时性能,该服务器还通过原生库支持 h2。
要启用此功能,您的应用程序需要添加一个额外的依赖项。
Spring Boot 管理 io.netty:netty-tcnative-boringssl-static 这个“全能 JAR”(uber jar)的版本,该 JAR 包含了所有平台的原生库。
开发者可以选择使用分类器(classifier)仅导入所需的依赖项(参见Netty 官方文档)。
配置 Web 服务器
通常,您应首先考虑使用众多可用的配置键之一,并通过在 application.properties 或 application.yaml 文件中添加新条目来自定义您的 Web 服务器。
请参阅 探索外部属性的内置选项)。
server.* 命名空间在此非常有用,它包含了如 server.tomcat.*、server.jetty.* 等用于服务器特定功能的命名空间。
请参阅 常用应用程序属性 列表。
前面的章节已经涵盖了许多常见用例,例如压缩、SSL 或 HTTP/2。
然而,如果您的用例没有对应的配置键,则应查看 WebServerFactoryCustomizer。
您可以声明此类组件并访问与您选择相关的服务器工厂:您应根据所选的服务器(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 |
||
Jetty |
||
Undertow |
||
Reactor |
N/A |
作为最后的手段,您还可以声明自己的 WebServerFactory Bean,它将覆盖 Spring Boot 提供的 Bean。
当您这样做时,自动配置的定制器仍会应用于您的自定义工厂,因此请谨慎使用此选项。
向应用程序添加 Servlet、Filter 或 Listener
在 Servlet 栈应用程序中,即使用 spring-boot-starter-web 时,有两种方式可以向您的应用程序添加 Servlet、Filter、ServletContextListener 以及 Servlet API 支持的其他监听器:
通过使用 Spring Bean 添加 Servlet、Filter 或 Listener
要通过使用 Spring Bean 添加 Servlet、Filter 或 Servlet *Listener,您必须为其提供 @Bean 定义。
当您想要注入配置或依赖项时,这样做非常有用。
然而,您必须非常小心,确保它们不会导致过多其他 Bean 的急切初始化,因为它们必须在应用程序生命周期的非常早期阶段安装到容器中。
(例如,让它们依赖于您的 DataSource 或 JPA 配置并不是一个好主意。)
您可以通过在首次使用时惰性初始化这些 Bean,而不是在初始化时立即初始化,来规避此类限制。
对于过滤器和 Servlet,您还可以通过添加 FilterRegistrationBean 或 ServletRegistrationBean 来注册映射和初始化参数,以替代底层组件或作为其补充。
您也可以使用 @ServletRegistration 和 @FilterRegistration 作为 ServletRegistrationBean 和 FilterRegistrationBean 的基于注解的替代方案。
|
如果在过滤器注册中未指定 |
与其他任何 Spring Bean 一样,您可以定义 Servlet 过滤器 Bean 的顺序;请务必查看将 Servlet、过滤器和监听器注册为 Spring Bean一节。
禁用 Servlet 或 Filter 的注册
正如前文所述,任何Servlet或Filter Bean 都会自动注册到 Servlet 容器中。
若要禁用特定Filter或Servlet 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、过滤器和监听器
@WebServlet、@WebFilter 和 @WebListener 注解的类可以通过使用 @ServletComponentScan 注解一个 @Configuration 类,并指定包含要注册组件的包,从而自动注册到嵌入式 Servlet 容器中。
默认情况下,@ServletComponentScan 会从被注解类所在的包开始扫描。
配置访问日志记录
可以通过各自的命名空间为 Tomcat、Undertow 和 Jetty 配置访问日志。
例如,以下设置使用自定义模式在 Tomcat 上记录访问日志。
-
Properties
-
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 的访问日志记录可以采用类似的方式进行配置,如下例所示:
-
Properties
-
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 的访问日志也可以按如下方式配置:
-
Properties
-
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 文档。
运行在前端代理服务器之后
如果你的应用程序运行在代理、负载均衡器之后,或在云环境中,请求信息(如主机、端口、协议方案等)可能会在传输过程中发生变化。
你的应用程序可能实际运行在 10.10.10.10:8080 上,但 HTTP 客户端应只看到 example.org。
RFC7239 “Forwarded Headers” 定义了 Forwarded HTTP 头;代理可以使用该头来提供有关原始请求的信息。
您可以配置应用程序读取这些头,并在创建链接以及通过 HTTP 302 响应、JSON 文档或 HTML 页面将其发送给客户端时自动使用这些信息。
此外,还存在一些非标准的头,例如 X-Forwarded-Host、X-Forwarded-Port、X-Forwarded-Proto、X-Forwarded-Ssl 和 X-Forwarded-Prefix。
如果代理添加了常用的 X-Forwarded-For 和 X-Forwarded-Proto 头部,只需将 server.forward-headers-strategy 设置为 NATIVE 即可支持这些头部。
使用此选项时,Web 服务器本身原生支持该功能;您可以查阅其具体文档以了解特定的行为。
如果这还不够,Spring Framework 为 Servlet 栈提供了 ForwardedHeaderFilter,并为响应式栈提供了 ForwardedHeaderTransformer。
您可以通过将 server.forward-headers-strategy 设置为 FRAMEWORK 在应用程序中使用它们。
如果你正在使用 Tomcat,并且在代理处终止 SSL,应将 server.tomcat.redirect-context-root 设置为 false。
这样可以在执行任何重定向前优先处理 X-Forwarded-Proto 请求头。 |
如果你的应用程序运行在受支持的云平台上,server.forward-headers-strategy 属性默认值为 NATIVE。
在所有其他情况下,默认值为 NONE。 |
自定义 Tomcat 的代理配置
如果你使用 Tomcat,还可以额外配置用于传递“转发”信息的请求头名称,如下例所示:
-
Properties
-
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 添加一个条目来自定义该 Valve 的配置,如下例所示:
-
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 设置为空来信任所有代理(但在生产环境中不要这样做)。 |
您可以通过关闭自动配置(为此,请设置 server.forward-headers-strategy=NONE)并使用 WebServerFactoryCustomizer Bean 添加新的 Valve 实例,从而完全控制 Tomcat 的 RemoteIpValve 配置。
使用 Tomcat 启用多个连接器
您可以向 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 属性来启用,如下例所示:
-
Properties
-
YAML
server.tomcat.mbeanregistry.enabled=true
server:
tomcat:
mbeanregistry:
enabled: true
使用 Undertow 启用多个监听器
向 UndertowBuilderCustomizer 添加一个 UndertowServletWebServerFactory,并为 io.undertow.Undertow.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。