Spring Boot 通过为 Spring Webflux 提供自动配置来简化响应式 Web 应用程序的开发。Spring中文文档

“Spring WebFlux 框架”

Spring WebFlux 是 Spring Framework 5.0 中引入的新反应式 Web 框架。 与 Spring MVC 不同,它不需要 servlet API,是完全异步和非阻塞的,并通过 Reactor 项目实现 Reactive Streams 规范。Spring中文文档

Spring WebFlux 有两种风格:函数式的和基于注释的。 基于注解的模型非常接近 Spring MVC 模型,如以下示例所示:Spring中文文档

import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/users")
public class MyRestController {

	private final UserRepository userRepository;

	private final CustomerRepository customerRepository;

	public MyRestController(UserRepository userRepository, CustomerRepository customerRepository) {
		this.userRepository = userRepository;
		this.customerRepository = customerRepository;
	}

	@GetMapping("/{userId}")
	public Mono<User> getUser(@PathVariable Long userId) {
		return this.userRepository.findById(userId);
	}

	@GetMapping("/{userId}/customers")
	public Flux<Customer> getUserCustomers(@PathVariable Long userId) {
		return this.userRepository.findById(userId).flatMapMany(this.customerRepository::findByUser);
	}

	@DeleteMapping("/{userId}")
	public Mono<Void> deleteUser(@PathVariable Long userId) {
		return this.userRepository.deleteById(userId);
	}

}
import org.springframework.web.bind.annotation.DeleteMapping
import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.PathVariable
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RestController
import reactor.core.publisher.Flux
import reactor.core.publisher.Mono

@RestController
@RequestMapping("/users")
class MyRestController(private val userRepository: UserRepository, private val customerRepository: CustomerRepository) {

	@GetMapping("/{userId}")
	fun getUser(@PathVariable userId: Long): Mono<User?> {
		return userRepository.findById(userId)
	}

	@GetMapping("/{userId}/customers")
	fun getUserCustomers(@PathVariable userId: Long): Flux<Customer> {
		return userRepository.findById(userId).flatMapMany { user: User? ->
			customerRepository.findByUser(user)
		}
	}

	@DeleteMapping("/{userId}")
	fun deleteUser(@PathVariable userId: Long): Mono<Void> {
		return userRepository.deleteById(userId)
	}

}

WebFlux 是 Spring 框架的一部分,详细信息在其参考文档中提供。Spring中文文档

“WebFlux.fn”(功能变体)将路由配置与请求的实际处理分开,如以下示例所示:Spring中文文档

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import org.springframework.web.reactive.function.server.RequestPredicate;
import org.springframework.web.reactive.function.server.RouterFunction;
import org.springframework.web.reactive.function.server.ServerResponse;

import static org.springframework.web.reactive.function.server.RequestPredicates.accept;
import static org.springframework.web.reactive.function.server.RouterFunctions.route;

@Configuration(proxyBeanMethods = false)
public class MyRoutingConfiguration {

	private static final RequestPredicate ACCEPT_JSON = accept(MediaType.APPLICATION_JSON);

	@Bean
	public RouterFunction<ServerResponse> monoRouterFunction(MyUserHandler userHandler) {
		return route()
				.GET("/{user}", ACCEPT_JSON, userHandler::getUser)
				.GET("/{user}/customers", ACCEPT_JSON, userHandler::getUserCustomers)
				.DELETE("/{user}", ACCEPT_JSON, userHandler::deleteUser)
				.build();
	}

}
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import org.springframework.http.MediaType
import org.springframework.web.reactive.function.server.RequestPredicates.DELETE
import org.springframework.web.reactive.function.server.RequestPredicates.GET
import org.springframework.web.reactive.function.server.RequestPredicates.accept
import org.springframework.web.reactive.function.server.RouterFunction
import org.springframework.web.reactive.function.server.RouterFunctions
import org.springframework.web.reactive.function.server.ServerResponse

@Configuration(proxyBeanMethods = false)
class MyRoutingConfiguration {

	@Bean
	fun monoRouterFunction(userHandler: MyUserHandler): RouterFunction<ServerResponse> {
		return RouterFunctions.route(
			GET("/{user}").and(ACCEPT_JSON), userHandler::getUser).andRoute(
			GET("/{user}/customers").and(ACCEPT_JSON), userHandler::getUserCustomers).andRoute(
			DELETE("/{user}").and(ACCEPT_JSON), userHandler::deleteUser)
	}

	companion object {
		private val ACCEPT_JSON = accept(MediaType.APPLICATION_JSON)
	}

}
import reactor.core.publisher.Mono;

import org.springframework.stereotype.Component;
import org.springframework.web.reactive.function.server.ServerRequest;
import org.springframework.web.reactive.function.server.ServerResponse;

@Component
public class MyUserHandler {

	public Mono<ServerResponse> getUser(ServerRequest request) {
		...
	}

	public Mono<ServerResponse> getUserCustomers(ServerRequest request) {
		...
	}

	public Mono<ServerResponse> deleteUser(ServerRequest request) {
		...
	}

}
import org.springframework.stereotype.Component
import org.springframework.web.reactive.function.server.ServerRequest
import org.springframework.web.reactive.function.server.ServerResponse
import reactor.core.publisher.Mono

@Component
class MyUserHandler {

	fun getUser(request: ServerRequest?): Mono<ServerResponse> {
		return ServerResponse.ok().build()
	}

	fun getUserCustomers(request: ServerRequest?): Mono<ServerResponse> {
		return ServerResponse.ok().build()
	}

	fun deleteUser(request: ServerRequest?): Mono<ServerResponse> {
		return ServerResponse.ok().build()
	}

}

“WebFlux.fn”是 Spring 框架的一部分,详细信息在其参考文档中提供。Spring中文文档

您可以根据需要定义任意数量的 Bean 来模块化路由器的定义。 如果您需要应用优先级,可以订购 Bean。RouterFunction

若要开始,请将该模块添加到应用程序中。spring-boot-starter-webfluxSpring中文文档

在应用程序中同时添加 和 模块会导致 Spring Boot 自动配置 Spring MVC,而不是 WebFlux。 之所以选择此行为,是因为许多 Spring 开发人员将 Spring MVC 应用程序添加到他们的 Spring MVC 应用程序中以使用反应式 . 您仍然可以通过将所选应用程序类型设置为 来强制执行您的选择。spring-boot-starter-webspring-boot-starter-webfluxspring-boot-starter-webfluxWebClientSpringApplication.setWebApplicationType(WebApplicationType.REACTIVE)

Spring WebFlux 自动配置

Spring Boot 为 Spring WebFlux 提供了自动配置,适用于大多数应用程序。Spring中文文档

自动配置在 Spring 的默认值之上添加了以下功能:Spring中文文档

如果要保留 Spring Boot WebFlux 功能,并且要添加其他 WebFlux 配置,则可以添加自己的类型类,但不添加 .@ConfigurationWebFluxConfigurer@EnableWebFluxSpring中文文档

如果要向自动配置的 添加其他自定义项,可以定义类型的 bean,并使用它们来修改 .HttpHandlerWebHttpHandlerBuilderCustomizerWebHttpHandlerBuilderSpring中文文档

如果你想完全控制 Spring WebFlux,你可以添加你自己的 annoted with .@Configuration@EnableWebFluxSpring中文文档

Spring WebFlux 转换服务

如果要自定义 Spring WebFlux 使用的,可以为 Bean 提供一个方法。ConversionServiceWebFluxConfigureraddFormattersSpring中文文档

也可以使用配置属性自定义转换。 如果未配置,则使用以下默认值:spring.webflux.format.*Spring中文文档

财产 DateTimeFormatter

spring.webflux.format.dateSpring中文文档

ofLocalizedDate(FormatStyle.SHORT)Spring中文文档

spring.webflux.format.timeSpring中文文档

ofLocalizedTime(FormatStyle.SHORT)Spring中文文档

spring.webflux.format.date-timeSpring中文文档

ofLocalizedDateTime(FormatStyle.SHORT)Spring中文文档

使用 HttpMessageReaders 和 HttpMessageWriters 的 HTTP 编解码器

Spring WebFlux 使用 和 接口来转换 HTTP 请求和响应。 它们被配置为通过查看类路径中可用的库来具有合理的默认值。HttpMessageReaderHttpMessageWriterCodecConfigurerSpring中文文档

Spring Boot 为编解码器提供专用配置属性。 它还通过使用实例应用进一步的自定义。 例如,配置键应用于 Jackson 编解码器。spring.codec.*CodecCustomizerspring.jackson.*Spring中文文档

如果需要添加或自定义编解码器,可以创建自定义组件,如以下示例所示:CodecCustomizerSpring中文文档

import org.springframework.boot.web.codec.CodecCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.codec.ServerSentEventHttpMessageReader;

@Configuration(proxyBeanMethods = false)
public class MyCodecsConfiguration {

	@Bean
	public CodecCustomizer myCodecCustomizer() {
		return (configurer) -> {
			configurer.registerDefaults(false);
			configurer.customCodecs().register(new ServerSentEventHttpMessageReader());
			// ...
		};
	}

}
import org.springframework.boot.web.codec.CodecCustomizer
import org.springframework.context.annotation.Bean
import org.springframework.http.codec.CodecConfigurer
import org.springframework.http.codec.ServerSentEventHttpMessageReader

class MyCodecsConfiguration {

	@Bean
	fun myCodecCustomizer(): CodecCustomizer {
		return CodecCustomizer { configurer: CodecConfigurer ->
			configurer.registerDefaults(false)
			configurer.customCodecs().register(ServerSentEventHttpMessageReader())
		}
	}

}

静态内容

默认情况下,Spring Boot 提供类路径中名为 (or or or ) 的目录中的静态内容。 它使用 from Spring WebFlux,以便您可以通过添加自己的方法并重写该方法来修改该行为。/static/public/resources/META-INF/resourcesResourceWebHandlerWebFluxConfigureraddResourceHandlersSpring中文文档

默认情况下,资源映射在 上,但您可以通过设置属性来调整它。 例如,可以按如下方式将所有资源重新定位:/**spring.webflux.static-path-pattern/resources/**Spring中文文档

spring.webflux.static-path-pattern=/resources/**
spring:
  webflux:
    static-path-pattern: "/resources/**"

您还可以使用 自定义静态资源位置。 这样做会将默认值替换为目录位置列表。 如果这样做,默认的欢迎页面检测将切换到您的自定义位置。 因此,如果启动时的任何位置都有一个,那就是应用程序的主页。spring.web.resources.static-locationsindex.htmlSpring中文文档

除了前面列出的“标准”静态资源位置之外,Webjars 内容还有一个特殊情况。 默认情况下,如果以 Webjars 格式打包,则任何带有路径的资源都会从 jar 文件中提供。 可以使用属性自定义路径。/webjars/**spring.webflux.webjars-path-patternSpring中文文档

Spring WebFlux 应用程序并不严格依赖于 servlet API,因此它们不能部署为 war 文件,也不使用目录。src/main/webapp

欢迎页面

Spring Boot 支持静态和模板化欢迎页面。 它首先在配置的静态内容位置中查找文件。 如果找不到模板,则查找模板。 如果找到任一,则会自动将其用作应用程序的欢迎页面。index.htmlindexSpring中文文档

这仅充当应用程序定义的实际索引路由的回退。 顺序由 Bean 的顺序定义,默认如下:HandlerMappingSpring中文文档

RouterFunctionMappingSpring中文文档

使用 Bean 声明的端点RouterFunctionSpring中文文档

RequestMappingHandlerMappingSpring中文文档

在 Bean 中声明的端点@ControllerSpring中文文档

RouterFunctionMapping欢迎页面Spring中文文档

欢迎页面支持Spring中文文档

模板引擎

除了 REST Web 服务之外,您还可以使用 Spring WebFlux 来提供动态 HTML 内容。 Spring WebFlux 支持多种模板技术,包括 Thymeleaf、FreeMarker 和 Mustache。Spring中文文档

Spring Boot 包括对以下模板引擎的自动配置支持:Spring中文文档

当您将其中一个模板引擎与默认配置一起使用时,将自动从 中选取模板。src/main/resources/templatesSpring中文文档

错误处理

Spring Boot 提供了一个以合理方式处理所有错误的功能。 它在处理顺序中的位置紧挨着 WebFlux 提供的处理程序,这些处理程序被认为是最后的。 对于计算机客户端,它会生成一个 JSON 响应,其中包含错误、HTTP 状态和异常消息的详细信息。 对于浏览器客户端,有一个“白标”错误处理程序,它以 HTML 格式呈现相同的数据。 您还可以提供自己的 HTML 模板来显示错误(请参阅下一节)。WebExceptionHandlerSpring中文文档

在直接在 Spring Boot 中自定义错误处理之前,您可以利用 Spring WebFlux 中的 RFC 7807 问题详细信息支持。 Spring WebFlux 可以生成具有媒体类型的自定义错误消息,例如:application/problem+jsonSpring中文文档

{
	"type": "https://example.org/problems/unknown-project",
	"title": "Unknown project",
	"status": 404,
	"detail": "No project found for id 'spring-unknown'",
	"instance": "/projects/spring-unknown"
}

可以通过设置为 来启用此支持。spring.webflux.problemdetails.enabledtrueSpring中文文档

自定义此功能的第一步通常涉及使用现有机制,但替换或扩充错误内容。 为此,您可以添加一个 bean 类型。ErrorAttributesSpring中文文档

要更改错误处理行为,您可以实现并注册该类型的 Bean 定义。 因为 an 是相当低级的,Spring Boot 还提供了一个方便的 WebFlux 函数方式来处理错误,如以下示例所示:ErrorWebExceptionHandlerErrorWebExceptionHandlerAbstractErrorWebExceptionHandlerSpring中文文档

import reactor.core.publisher.Mono;

import org.springframework.boot.autoconfigure.web.WebProperties;
import org.springframework.boot.autoconfigure.web.reactive.error.AbstractErrorWebExceptionHandler;
import org.springframework.boot.web.reactive.error.ErrorAttributes;
import org.springframework.context.ApplicationContext;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.codec.ServerCodecConfigurer;
import org.springframework.stereotype.Component;
import org.springframework.web.reactive.function.server.RouterFunction;
import org.springframework.web.reactive.function.server.RouterFunctions;
import org.springframework.web.reactive.function.server.ServerRequest;
import org.springframework.web.reactive.function.server.ServerResponse;
import org.springframework.web.reactive.function.server.ServerResponse.BodyBuilder;

@Component
public class MyErrorWebExceptionHandler extends AbstractErrorWebExceptionHandler {

	public MyErrorWebExceptionHandler(ErrorAttributes errorAttributes, WebProperties webProperties,
			ApplicationContext applicationContext, ServerCodecConfigurer serverCodecConfigurer) {
		super(errorAttributes, webProperties.getResources(), applicationContext);
		setMessageReaders(serverCodecConfigurer.getReaders());
		setMessageWriters(serverCodecConfigurer.getWriters());
	}

	@Override
	protected RouterFunction<ServerResponse> getRoutingFunction(ErrorAttributes errorAttributes) {
		return RouterFunctions.route(this::acceptsXml, this::handleErrorAsXml);
	}

	private boolean acceptsXml(ServerRequest request) {
		return request.headers().accept().contains(MediaType.APPLICATION_XML);
	}

	public Mono<ServerResponse> handleErrorAsXml(ServerRequest request) {
		BodyBuilder builder = ServerResponse.status(HttpStatus.INTERNAL_SERVER_ERROR);
		// ... additional builder calls
		return builder.build();
	}

}
import org.springframework.boot.autoconfigure.web.WebProperties
import org.springframework.boot.autoconfigure.web.reactive.error.AbstractErrorWebExceptionHandler
import org.springframework.boot.web.reactive.error.ErrorAttributes
import org.springframework.context.ApplicationContext
import org.springframework.http.HttpStatus
import org.springframework.http.MediaType
import org.springframework.http.codec.ServerCodecConfigurer
import org.springframework.stereotype.Component
import org.springframework.web.reactive.function.server.RouterFunction
import org.springframework.web.reactive.function.server.RouterFunctions
import org.springframework.web.reactive.function.server.ServerRequest
import org.springframework.web.reactive.function.server.ServerResponse
import reactor.core.publisher.Mono

@Component
class MyErrorWebExceptionHandler(
		errorAttributes: ErrorAttributes, webProperties: WebProperties,
		applicationContext: ApplicationContext, serverCodecConfigurer: ServerCodecConfigurer
) : AbstractErrorWebExceptionHandler(errorAttributes, webProperties.resources, applicationContext) {

	init {
		setMessageReaders(serverCodecConfigurer.readers)
		setMessageWriters(serverCodecConfigurer.writers)
	}

	override fun getRoutingFunction(errorAttributes: ErrorAttributes): RouterFunction<ServerResponse> {
		return RouterFunctions.route(this::acceptsXml, this::handleErrorAsXml)
	}

	private fun acceptsXml(request: ServerRequest): Boolean {
		return request.headers().accept().contains(MediaType.APPLICATION_XML)
	}

	fun handleErrorAsXml(request: ServerRequest): Mono<ServerResponse> {
		val builder = ServerResponse.status(HttpStatus.INTERNAL_SERVER_ERROR)
		// ... additional builder calls
		return builder.build()
	}

}

为了更全面地了解情况,您还可以直接子类化并重写特定方法。DefaultErrorWebExceptionHandlerSpring中文文档

在某些情况下,Web 观察或指标基础结构不会记录在控制器级别处理的错误。 应用程序可以通过在观察上下文中设置已处理的异常来确保将此类异常与观察记录在一起。Spring中文文档

自定义错误页面

如果要显示给定状态代码的自定义 HTML 错误页,可以添加解析自 的视图,例如,通过将文件添加到目录。 错误页面可以是静态 HTML(即,添加到任何静态资源目录下)或使用模板构建的。 文件的名称应为确切的状态代码、状态代码系列掩码,或者如果没有其他匹配项,则为默认值。 请注意,默认错误视图的路径是 ,而使用 Spring MVC 时,默认错误视图是 。error/*/errorerrorerror/errorerrorSpring中文文档

例如,若要映射到静态 HTML 文件,目录结构如下所示:404Spring中文文档

src/
 +- main/
     +- java/
     |   + <source code>
     +- resources/
         +- public/
             +- error/
             |   +- 404.html
             +- <other public assets>

要使用 Mustache 模板映射所有错误,目录结构如下所示:5xxSpring中文文档

src/
 +- main/
     +- java/
     |   + <source code>
     +- resources/
         +- templates/
             +- error/
             |   +- 5xx.mustache
             +- <other templates>

网页过滤器

Spring WebFlux 提供了一个接口,可以实现该接口来过滤 HTTP 请求-响应交换。 在应用程序上下文中找到的 Bean 将自动用于过滤每个交换。WebFilterWebFilterSpring中文文档

如果过滤器的顺序很重要,则可以用 实现或注释 。 Spring Boot 自动配置可能会为您配置 Web 过滤器。 执行此操作时,将使用下表中显示的订单:Ordered@OrderSpring中文文档

网页过滤器 次序

WebFilterChainProxy(春季安全)Spring中文文档

-100Spring中文文档

HttpExchangesWebFilterSpring中文文档

Ordered.LOWEST_PRECEDENCE - 10Spring中文文档

您可以根据需要定义任意数量的 Bean 来模块化路由器的定义。 如果您需要应用优先级,可以订购 Bean。RouterFunction
在应用程序中同时添加 和 模块会导致 Spring Boot 自动配置 Spring MVC,而不是 WebFlux。 之所以选择此行为,是因为许多 Spring 开发人员将 Spring MVC 应用程序添加到他们的 Spring MVC 应用程序中以使用反应式 . 您仍然可以通过将所选应用程序类型设置为 来强制执行您的选择。spring-boot-starter-webspring-boot-starter-webfluxspring-boot-starter-webfluxWebClientSpringApplication.setWebApplicationType(WebApplicationType.REACTIVE)
财产 DateTimeFormatter

spring.webflux.format.dateSpring中文文档

ofLocalizedDate(FormatStyle.SHORT)Spring中文文档

spring.webflux.format.timeSpring中文文档

ofLocalizedTime(FormatStyle.SHORT)Spring中文文档

spring.webflux.format.date-timeSpring中文文档

ofLocalizedDateTime(FormatStyle.SHORT)Spring中文文档

Spring WebFlux 应用程序并不严格依赖于 servlet API,因此它们不能部署为 war 文件,也不使用目录。src/main/webapp

RouterFunctionMappingSpring中文文档

使用 Bean 声明的端点RouterFunctionSpring中文文档

RequestMappingHandlerMappingSpring中文文档

在 Bean 中声明的端点@ControllerSpring中文文档

RouterFunctionMapping欢迎页面Spring中文文档

欢迎页面支持Spring中文文档

网页过滤器 次序

WebFilterChainProxy(春季安全)Spring中文文档

-100Spring中文文档

HttpExchangesWebFilterSpring中文文档

Ordered.LOWEST_PRECEDENCE - 10Spring中文文档

嵌入式反应式服务器支持

Spring Boot 包括对以下嵌入式响应式 Web 服务器的支持:Reactor Netty、Tomcat、Jetty 和 Undertow。 大多数开发人员使用适当的“Starter”来获取完全配置的实例。 默认情况下,嵌入式服务器侦听端口 8080 上的 HTTP 请求。Spring中文文档

自定义反应式服务器

可以使用 Spring 属性配置常见的反应式 Web 服务器设置。 通常,您将在 or 文件中定义属性。Environmentapplication.propertiesapplication.yamlSpring中文文档

常见的服务器设置包括:Spring中文文档

Spring Boot 会尽可能多地公开通用设置,但这并不总是可行的。 对于这些情况,专用命名空间(如)提供特定于服务器的自定义项。server.netty.*Spring中文文档

有关完整列表,请参阅 ServerProperties 类。

程序化定制

如果需要以编程方式配置响应式 Web 服务器,可以注册实现该接口的 Spring bean。 提供对 的访问,其中包括许多自定义 setter 方法。 以下示例演示如何以编程方式设置端口:WebServerFactoryCustomizerWebServerFactoryCustomizerConfigurableReactiveWebServerFactorySpring中文文档

import org.springframework.boot.web.reactive.server.ConfigurableReactiveWebServerFactory;
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
import org.springframework.stereotype.Component;

@Component
public class MyWebServerFactoryCustomizer implements WebServerFactoryCustomizer<ConfigurableReactiveWebServerFactory> {

	@Override
	public void customize(ConfigurableReactiveWebServerFactory server) {
		server.setPort(9000);
	}

}
import org.springframework.boot.web.server.WebServerFactoryCustomizer
import org.springframework.boot.web.reactive.server.ConfigurableReactiveWebServerFactory
import org.springframework.stereotype.Component

@Component
class MyWebServerFactoryCustomizer : WebServerFactoryCustomizer<ConfigurableReactiveWebServerFactory> {

	override fun customize(server: ConfigurableReactiveWebServerFactory) {
		server.setPort(9000)
	}

}

JettyReactiveWebServerFactory、 、 和 是专用变体,分别为 Jetty、Reactor Netty、Tomcat 和 Undertow 提供了额外的自定义设置器方法。 以下示例演示如何自定义以提供对特定于 Reactor Netty 的配置选项的访问:NettyReactiveWebServerFactoryTomcatReactiveWebServerFactoryUndertowReactiveWebServerFactoryConfigurableReactiveWebServerFactoryNettyReactiveWebServerFactorySpring中文文档

import java.time.Duration;

import org.springframework.boot.web.embedded.netty.NettyReactiveWebServerFactory;
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
import org.springframework.stereotype.Component;

@Component
public class MyNettyWebServerFactoryCustomizer implements WebServerFactoryCustomizer<NettyReactiveWebServerFactory> {

	@Override
	public void customize(NettyReactiveWebServerFactory factory) {
		factory.addServerCustomizers((server) -> server.idleTimeout(Duration.ofSeconds(20)));
	}

}
import org.springframework.boot.web.embedded.netty.NettyReactiveWebServerFactory
import org.springframework.boot.web.server.WebServerFactoryCustomizer
import org.springframework.stereotype.Component
import java.time.Duration

@Component
class MyNettyWebServerFactoryCustomizer : WebServerFactoryCustomizer<NettyReactiveWebServerFactory> {

	override fun customize(factory: NettyReactiveWebServerFactory) {
		factory.addServerCustomizers({ server -> server.idleTimeout(Duration.ofSeconds(20)) })
	}

}

直接自定义 ConfigurableReactiveWebServerFactory

对于需要从 扩展的更高级用例,您可以自己公开此类类型的 Bean。ReactiveWebServerFactorySpring中文文档

为许多配置选项提供了 Setter。 如果您需要做一些更奇特的事情,还提供了几个受保护的方法“钩子”。 有关详细信息,请参阅源代码文档Spring中文文档

自动配置的定制工具仍应用于您的自定义工厂,因此请谨慎使用该选项。
有关完整列表,请参阅 ServerProperties 类。
自动配置的定制工具仍应用于您的自定义工厂,因此请谨慎使用该选项。

反应式服务器资源配置

自动配置 Reactor Netty 或 Jetty 服务器时,Spring Boot 将创建特定的 bean,这些 bean 将为服务器实例提供 HTTP 资源:或 .ReactorResourceFactoryJettyResourceFactorySpring中文文档

默认情况下,这些资源也将与 Reactor Netty 和 Jetty 客户端共享,以获得最佳性能,前提是:Spring中文文档

开发人员可以通过提供自定义或 bean 来覆盖 Jetty 和 Reactor Netty 的资源配置 - 这将应用于客户端和服务器。ReactorResourceFactoryJettyResourceFactorySpring中文文档

可以在 WebClient 运行时部分中了解有关客户端资源配置的详细信息。Spring中文文档