|
此版本仍在开发中,尚未被视为稳定版本。如需最新稳定版本,请使用 Spring Boot 4.0.4! |
嵌入式 Web 服务器
每个Spring Boot Web应用程序都包含一个嵌入式Web服务器。 此功能引发了许多如何操作的问题,包括如何更改嵌入式服务器以及如何配置嵌入式服务器。 本节将回答这些问题。
使用其他 Web 服务器
许多 Spring Boot Starters包含默认的嵌入式容器。
-
对于 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服务器提供了单独的Starters。
以下 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")
}
}
}
spring-boot-starter-reactor-netty 是使用 WebClient 类所必需的,因此即使您需要包含不同的 HTTP 服务器,也可能需要保留对 Netty 的依赖。 |
禁用 Web 服务器
如果您的类路径包含启动Web服务器的必要组件,Spring Boot将自动启动它。
要禁用此行为,请在您的 WebApplicationType 中配置 application.properties,如下面的示例所示:
-
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访问服务器运行的端口。
获取该值并确保它已初始化的最佳方法是添加一个类型为@Bean的ApplicationListener<WebServerInitializedEvent>,并在发布时从事件中提取容器。
使用 @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 响应压缩
Jetty、Tomcat、Reactor Netty 和 Undertow 支持 HTTP 响应压缩。
可以在 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
可以通过设置各种 server.ssl.* 属性来以声明方式配置 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捆绑包 中配置,并如本示例所示应用于网络服务器:
-
Properties
-
YAML
server.port=8443
server.ssl.bundle=example
server:
port: 8443
ssl:
bundle: "example"
|
使用 bundle 时, |
配置服务器名称指示 (SNI)
Tomcat、Netty 和 Undertow 可以配置为为单个主机名使用唯一的 SSL 信任材料,以支持服务器名称指示 (SNI)。 Jetty 不支持 SNI 配置,但如果为其提供多个证书,Jetty 可以自动设置 SNI。
假设已配置名为 web、web-alt1 和 web-alt2 的 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终止的代理服务器后面运行时,您可能希望使用h2c。
Tomcat 的 HTTP/2 支持
Spring Boot 默认附带 Tomcat 10.1.x,它开箱即用地支持 h2c 和 h2。
或者,如果主机操作系统上已安装该库及其依赖项,您可以使用 libtcnative 来获得对 h2 的支持。
必须将库目录提供给JVM库路径,如果尚未提供的话。
您可以使用如-Djava.library.path=/usr/local/opt/tomcat-native/lib之类的JVM参数来实现。
更多相关信息请参阅官方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“uber jar”管理版本。
开发者可以使用分类器选择仅导入所需的依赖项(参见 Netty 官方文档)。
配置 Web 服务器
通常,您应首先考虑使用许多可用的配置键,并通过在您的 application.properties 或 application.yaml 文件中添加新条目来自定义您的网络服务器。
参见 发现内置的外部属性选项).
server.* 命名空间在这里非常有用,它包括诸如 server.tomcat.*、server.jetty.* 等命名空间以及其他用于服务器特定功能的命名空间。
参见 常用应用程序属性 的列表。
前面的章节已经涵盖了许多常见用例,例如压缩、SSL 或 HTTP/2。
但是,如果您的用例没有对应的配置键,则应查看 WebServerFactoryCustomizer。
您可以声明此类组件并访问与您选择相关的服务器工厂:您应该为所选的服务器(Tomcat、Jetty、Reactor Netty、Undertow)和所选的 Web 技术栈(servlet 或 reactive)选择相应的变体。
以下示例适用于带有 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 |
||
反应器 |
N/A |
作为最后的手段,您还可以声明自己的 WebServerFactory bean,它将覆盖 Spring Boot 提供的那个。
当您这样做时,自动配置的定制器仍会应用于您的自定义工厂,因此请谨慎使用该选项。
向应用程序添加 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、Filter和Listener注册为Spring Bean 部分。
禁用 Servlet 或过滤器的注册
如前所述,任何 所述 的 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、Filter 和 Listener
@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 添加条目来自定义阀门的配置,如下例所示:
-
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的<a t="C3"><code>0</code></a>的配置,通过关闭自动配置(为此,请将<code>1</code>设置为true),并使用<a t="C4"><code>2</code></a> bean添加一个新的valve实例。
在 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。