对于最新的稳定版本,请使用 Spring Framework 6.2.4spring-doc.cadn.net.cn

WebFlux 配置

WebFlux Java 配置声明了处理 请求,并且它提供了一个 API 来 自定义配置。这意味着您不需要了解底层 由 Java 配置创建的 bean。但是,如果您想了解它们, 您可以在WebFluxConfigurationSupport或阅读更多关于它们是什么的信息 在 Special Bean Types 中。spring-doc.cadn.net.cn

对于配置 API 中不可用的更高级自定义,您可以 通过高级配置模式获得对配置的完全控制。spring-doc.cadn.net.cn

启用 WebFlux 配置

您可以使用@EnableWebFlux注解,如下例所示:spring-doc.cadn.net.cn

@Configuration
@EnableWebFlux
public class WebConfig {
}
@Configuration
@EnableWebFlux
class WebConfig

前面的示例注册了许多 Spring WebFlux 基础结构 bean 并适应依赖项 available on the classpath — 用于 JSON、XML 等。spring-doc.cadn.net.cn

WebFlux 配置 API

在 Java 配置中,您可以实现WebFluxConfigurer接口 如下例所示:spring-doc.cadn.net.cn

@Configuration
@EnableWebFlux
public class WebConfig implements WebFluxConfigurer {

	// Implement configuration methods...
}
@Configuration
@EnableWebFlux
class WebConfig : WebFluxConfigurer {

	// Implement configuration methods...
}

转换, 格式设置

默认情况下,会安装各种数字和日期类型的格式化程序,以及支持 用于自定义@NumberFormat@DateTimeFormaton fields 和 parameters 上。spring-doc.cadn.net.cn

要在 Java 配置中注册自定义格式化程序和转换器,请使用以下内容:spring-doc.cadn.net.cn

@Configuration
@EnableWebFlux
public class WebConfig implements WebFluxConfigurer {

	@Override
	public void addFormatters(FormatterRegistry registry) {
		// ...
	}

}
@Configuration
@EnableWebFlux
class WebConfig : WebFluxConfigurer {

	override fun addFormatters(registry: FormatterRegistry) {
		// ...
	}
}

默认情况下,Spring WebFlux 在解析和格式化日期时会考虑请求 Locale 值。这适用于日期表示为带有 “input” 形式的字符串的表单 领域。但是,对于“日期”和“时间”表单字段,浏览器使用定义的固定格式 在 HTML 规范中。对于此类情况,可以按如下方式自定义日期和时间格式:spring-doc.cadn.net.cn

@Configuration
@EnableWebFlux
public class WebConfig implements WebFluxConfigurer {

	@Override
	public void addFormatters(FormatterRegistry registry) {
		DateTimeFormatterRegistrar registrar = new DateTimeFormatterRegistrar();
		registrar.setUseIsoFormat(true);
		registrar.registerFormatters(registry);
     	}
}
@Configuration
@EnableWebFlux
class WebConfig : WebFluxConfigurer {

	override fun addFormatters(registry: FormatterRegistry) {
		val registrar = DateTimeFormatterRegistrar()
		registrar.setUseIsoFormat(true)
		registrar.registerFormatters(registry)
	}
}
FormatterRegistrarSPI 系列FormattingConversionServiceFactoryBean有关何时 用FormatterRegistrar实现。

验证

默认情况下,如果存在 Bean Validation 在 Classpath(例如,Hibernate Validator)上,LocalValidatorFactoryBean注册为全局验证器,以便与@Valid@Validated@Controllermethod 参数。spring-doc.cadn.net.cn

在 Java 配置中,您可以自定义全局Validator实例 如下例所示:spring-doc.cadn.net.cn

@Configuration
@EnableWebFlux
public class WebConfig implements WebFluxConfigurer {

	@Override
	public Validator getValidator() {
		// ...
	}

}
@Configuration
@EnableWebFlux
class WebConfig : WebFluxConfigurer {

	override fun getValidator(): Validator {
		// ...
	}

}

请注意,您也可以注册Validator实现, 如下例所示:spring-doc.cadn.net.cn

@Controller
public class MyController {

	@InitBinder
	protected void initBinder(WebDataBinder binder) {
		binder.addValidators(new FooValidator());
	}

}
@Controller
class MyController {

	@InitBinder
	protected fun initBinder(binder: WebDataBinder) {
		binder.addValidators(FooValidator())
	}
}
如果您需要LocalValidatorFactoryBean注入某个位置,创建一个 bean 并 标记@Primary以避免与 MVC 配置中声明的冲突。

内容类型解析程序

您可以配置 Spring WebFlux 确定请求的媒体类型的方式@Controller实例。默认情况下,只有Acceptheader 中, 但您也可以启用基于查询参数的策略。spring-doc.cadn.net.cn

以下示例显示如何自定义请求的内容类型解析:spring-doc.cadn.net.cn

@Configuration
@EnableWebFlux
public class WebConfig implements WebFluxConfigurer {

	@Override
	public void configureContentTypeResolver(RequestedContentTypeResolverBuilder builder) {
		// ...
	}
}
@Configuration
@EnableWebFlux
class WebConfig : WebFluxConfigurer {

	override fun configureContentTypeResolver(builder: RequestedContentTypeResolverBuilder) {
		// ...
	}
}

HTTP 消息编解码器

以下示例显示如何自定义请求和响应正文的读取和写入方式:spring-doc.cadn.net.cn

@Configuration
@EnableWebFlux
public class WebConfig implements WebFluxConfigurer {

	@Override
	public void configureHttpMessageCodecs(ServerCodecConfigurer configurer) {
		configurer.defaultCodecs().maxInMemorySize(512 * 1024);
	}
}
@Configuration
@EnableWebFlux
class WebConfig : WebFluxConfigurer {

	override fun configureHttpMessageCodecs(configurer: ServerCodecConfigurer) {
		configurer.defaultCodecs().maxInMemorySize(512 * 1024)
	}
}

ServerCodecConfigurer提供一组默认读取器和写入器。您可以使用它来添加 更多读取器和写入器,自定义默认读取器和写入器,或完全替换默认读取器和写入器。spring-doc.cadn.net.cn

对于 Jackson JSON 和 XML,请考虑使用Jackson2ObjectMapperBuilder, ,它使用以下属性自定义 Jackson 的默认属性:spring-doc.cadn.net.cn

如果在 Classpath 中检测到以下众所周知的模块,它还会自动注册它们:spring-doc.cadn.net.cn

View 解析程序

以下示例显示如何配置视图分辨率:spring-doc.cadn.net.cn

@Configuration
@EnableWebFlux
public class WebConfig implements WebFluxConfigurer {

	@Override
	public void configureViewResolvers(ViewResolverRegistry registry) {
		// ...
	}
}
@Configuration
@EnableWebFlux
class WebConfig : WebFluxConfigurer {

	override fun configureViewResolvers(registry: ViewResolverRegistry) {
		// ...
	}
}

ViewResolverRegistry具有视图技术的快捷方式,Spring Framework 使用 集成。以下示例使用 FreeMarker(还需要配置 基础 FreeMarker 视图技术):spring-doc.cadn.net.cn

@Configuration
@EnableWebFlux
public class WebConfig implements WebFluxConfigurer {


	@Override
	public void configureViewResolvers(ViewResolverRegistry registry) {
		registry.freeMarker();
	}

	// Configure Freemarker...

	@Bean
	public FreeMarkerConfigurer freeMarkerConfigurer() {
		FreeMarkerConfigurer configurer = new FreeMarkerConfigurer();
		configurer.setTemplateLoaderPath("classpath:/templates");
		return configurer;
	}
}
@Configuration
@EnableWebFlux
class WebConfig : WebFluxConfigurer {

	override fun configureViewResolvers(registry: ViewResolverRegistry) {
		registry.freeMarker()
	}

	// Configure Freemarker...

	@Bean
	fun freeMarkerConfigurer() = FreeMarkerConfigurer().apply {
		setTemplateLoaderPath("classpath:/templates")
	}
}

您还可以插入任何ViewResolver实现,如下例所示:spring-doc.cadn.net.cn

@Configuration
@EnableWebFlux
public class WebConfig implements WebFluxConfigurer {


	@Override
	public void configureViewResolvers(ViewResolverRegistry registry) {
		ViewResolver resolver = ... ;
		registry.viewResolver(resolver);
	}
}
@Configuration
@EnableWebFlux
class WebConfig : WebFluxConfigurer {

	override fun configureViewResolvers(registry: ViewResolverRegistry) {
		val resolver: ViewResolver = ...
		registry.viewResolver(resolver
	}
}

支持 Content Negotiation 和呈现其他格式 通过视图分辨率(除了 HTML),您可以配置一个或多个基于 在HttpMessageWriterViewimplementation 的 API 中,它接受spring-web.以下示例显示了如何执行此作:spring-doc.cadn.net.cn

@Configuration
@EnableWebFlux
public class WebConfig implements WebFluxConfigurer {


	@Override
	public void configureViewResolvers(ViewResolverRegistry registry) {
		registry.freeMarker();

		Jackson2JsonEncoder encoder = new Jackson2JsonEncoder();
		registry.defaultViews(new HttpMessageWriterView(encoder));
	}

	// ...
}
@Configuration
@EnableWebFlux
class WebConfig : WebFluxConfigurer {


	override fun configureViewResolvers(registry: ViewResolverRegistry) {
		registry.freeMarker()

		val encoder = Jackson2JsonEncoder()
		registry.defaultViews(HttpMessageWriterView(encoder))
	}

	// ...
}

有关与 Spring WebFlux 集成的视图技术的更多信息,请参见 View Technologiesspring-doc.cadn.net.cn

静态资源

此选项提供了一种从列表中提供静态资源的便捷方法Resource基于位置。spring-doc.cadn.net.cn

在下一个示例中,给定一个以/resources,则相对路径为 用于查找和提供相对于/static在 Classpath 上。资源 提供一年的未来到期时间,以确保最大限度地使用浏览器缓存 以及减少浏览器发出的 HTTP 请求。这Last-Modifiedheader 也是 已评估,如果存在,则为304返回 status code。以下清单显示了 示例:spring-doc.cadn.net.cn

@Configuration
@EnableWebFlux
public class WebConfig implements WebFluxConfigurer {

	@Override
	public void addResourceHandlers(ResourceHandlerRegistry registry) {
		registry.addResourceHandler("/resources/**")
				.addResourceLocations("/public", "classpath:/static/")
				.setCacheControl(CacheControl.maxAge(365, TimeUnit.DAYS));
	}

}
@Configuration
@EnableWebFlux
class WebConfig : WebFluxConfigurer {

	override fun addResourceHandlers(registry: ResourceHandlerRegistry) {
		registry.addResourceHandler("/resources/**")
				.addResourceLocations("/public", "classpath:/static/")
				.setCacheControl(CacheControl.maxAge(365, TimeUnit.DAYS))
	}
}

资源处理程序还支持ResourceResolverimplementations 和ResourceTransformer实现 可用于创建用于处理优化资源的工具链。spring-doc.cadn.net.cn

您可以使用VersionResourceResolver对于基于 MD5 哈希的版本控制资源 URL 根据内容、固定的应用程序版本或其他信息计算得出。一个ContentVersionStrategy(MD5 哈希) 是一个不错的选择,但有一些明显的例外(例如 JavaScript 资源)。spring-doc.cadn.net.cn

以下示例演示如何使用VersionResourceResolver在 Java 配置中:spring-doc.cadn.net.cn

@Configuration
@EnableWebFlux
public class WebConfig implements WebFluxConfigurer {

	@Override
	public void addResourceHandlers(ResourceHandlerRegistry registry) {
		registry.addResourceHandler("/resources/**")
				.addResourceLocations("/public/")
				.resourceChain(true)
				.addResolver(new VersionResourceResolver().addContentVersionStrategy("/**"));
	}

}
@Configuration
@EnableWebFlux
class WebConfig : WebFluxConfigurer {

	override fun addResourceHandlers(registry: ResourceHandlerRegistry) {
		registry.addResourceHandler("/resources/**")
				.addResourceLocations("/public/")
				.resourceChain(true)
				.addResolver(VersionResourceResolver().addContentVersionStrategy("/**"))
	}

}

您可以使用ResourceUrlProvider重写 URL 并应用完整的解析器链,以及 转换器(例如,插入版本)。WebFlux 配置提供了一个ResourceUrlProvider这样就可以注入到其他人身上。spring-doc.cadn.net.cn

与 Spring MVC 不同,目前在 WebFlux 中,没有办法透明地重写 static 资源 URL,因为没有可以使用非阻塞链的视图技术 的旋转转换器。当仅提供本地资源时,解决方法是使用ResourceUrlProvider直接 (例如,通过自定义元素) 和 Block 进行。spring-doc.cadn.net.cn

请注意,当同时使用EncodedResourceResolver(例如,Gzip、Brotli 编码)和VersionedResourceResolver,它们必须按该顺序注册,以确保基于内容的 版本始终基于未编码的文件进行可靠计算。spring-doc.cadn.net.cn

对于 WebJar,/webjars/jquery/1.2.0/jquery.min.js是推荐且最有效的使用它们的方式。 相关资源位置使用 Spring Boot 开箱即用地配置(也可以配置 手动通过ResourceHandlerRegistry),并且不需要添加org.webjars:webjars-locator-coreDependency。spring-doc.cadn.net.cn

无版本的 URL,如/webjars/jquery/jquery.min.js通过WebJarsResourceResolverorg.webjars:webjars-locator-core库存在于类路径中,但代价是 类路径扫描可能会减慢应用程序启动速度。解析器可以将 URL 重写为 包括 jar 的版本,并且还可以与没有版本的传入 URL 进行匹配 — 例如,从/webjars/jquery/jquery.min.js/webjars/jquery/1.2.0/jquery.min.js.spring-doc.cadn.net.cn

基于ResourceHandlerRegistry提供更多选项 进行精细控制,例如上次修改的行为和优化的资源解析。

路径匹配

您可以自定义与路径匹配相关的选项。有关各个选项的详细信息,请参阅PathMatchConfigurerjavadoc 的 以下示例演示如何使用PathMatchConfigurer:spring-doc.cadn.net.cn

import org.springframework.context.annotation.Configuration;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.method.HandlerTypePredicate;
import org.springframework.web.reactive.config.EnableWebFlux;
import org.springframework.web.reactive.config.PathMatchConfigurer;
import org.springframework.web.reactive.config.WebFluxConfigurer;

@Configuration
@EnableWebFlux
public class WebConfig implements WebFluxConfigurer {

	@Override
	public void configurePathMatching(PathMatchConfigurer configurer) {
		configurer.addPathPrefix(
				"/api", HandlerTypePredicate.forAnnotation(RestController.class));
	}
}
import org.springframework.context.annotation.Configuration
import org.springframework.web.bind.annotation.RestController
import org.springframework.web.method.HandlerTypePredicate
import org.springframework.web.reactive.config.EnableWebFlux
import org.springframework.web.reactive.config.PathMatchConfigurer
import org.springframework.web.reactive.config.WebFluxConfigurer

@Configuration
@EnableWebFlux
class WebConfig : WebFluxConfigurer {

	override fun configurePathMatching(configurer: PathMatchConfigurer) {
		configurer.addPathPrefix(
			"/api", HandlerTypePredicate.forAnnotation(RestController::class.java))
	}
}

Spring WebFlux relies on a parsed representation of the request path called RequestPath for access to decoded path segment values, with semicolon content removed (that is, path or matrix variables). That means, unlike in Spring MVC, you need not indicate whether to decode the request path nor whether to remove semicolon content for path matching purposes.spring-doc.cadn.net.cn

Spring WebFlux also does not support suffix pattern matching, unlike in Spring MVC, where we are also recommend moving away from reliance on it.spring-doc.cadn.net.cn

Blocking Execution

The WebFlux Java config allows you to customize blocking execution in WebFlux.spring-doc.cadn.net.cn

You can have blocking controller methods called on a separate thread by providing an AsyncTaskExecutor such as the VirtualThreadTaskExecutor as follows:spring-doc.cadn.net.cn

@Configuration
@EnableWebFlux
public class WebConfig implements WebFluxConfigurer {

	@Override
	public void configureBlockingExecution(BlockingExecutionConfigurer configurer) {
		AsyncTaskExecutor executor = ...
		configurer.setExecutor(executor);
	}
}
@Configuration
@EnableWebFlux
class WebConfig : WebFluxConfigurer {

	@Override
	fun configureBlockingExecution(configurer: BlockingExecutionConfigurer) {
		val executor = ...
		configurer.setExecutor(executor)
	}
}

By default, controller methods whose return type is not recognized by the configured ReactiveAdapterRegistry are considered blocking, but you can set a custom controller method predicate via BlockingExecutionConfigurer.spring-doc.cadn.net.cn

WebSocketService

The WebFlux Java config declares of a WebSocketHandlerAdapter bean which provides support for the invocation of WebSocket handlers. That means all that remains to do in order to handle a WebSocket handshake request is to map a WebSocketHandler to a URL via SimpleUrlHandlerMapping.spring-doc.cadn.net.cn

In some cases it may be necessary to create the WebSocketHandlerAdapter bean with a provided WebSocketService service which allows configuring WebSocket server properties. For example:spring-doc.cadn.net.cn

@Configuration
@EnableWebFlux
public class WebConfig implements WebFluxConfigurer {

	@Override
	public WebSocketService getWebSocketService() {
		TomcatRequestUpgradeStrategy strategy = new TomcatRequestUpgradeStrategy();
		strategy.setMaxSessionIdleTimeout(0L);
		return new HandshakeWebSocketService(strategy);
	}
}
@Configuration
@EnableWebFlux
class WebConfig : WebFluxConfigurer {

	@Override
	fun webSocketService(): WebSocketService {
		val strategy = TomcatRequestUpgradeStrategy().apply {
			setMaxSessionIdleTimeout(0L)
		}
		return HandshakeWebSocketService(strategy)
	}
}

Advanced Configuration Mode

@EnableWebFlux imports DelegatingWebFluxConfiguration that:spring-doc.cadn.net.cn

For advanced mode, you can remove @EnableWebFlux and extend directly from DelegatingWebFluxConfiguration instead of implementing WebFluxConfigurer, as the following example shows:spring-doc.cadn.net.cn

@Configuration
public class WebConfig extends DelegatingWebFluxConfiguration {

	// ...
}
@Configuration
class WebConfig : DelegatingWebFluxConfiguration {

	// ...
}

You can keep existing methods in WebConfig, but you can now also override bean declarations from the base class and still have any number of other WebMvcConfigurer implementations on the classpath.spring-doc.cadn.net.cn