对于最新的稳定版本,请使用 Spring Framework 6.2.0spring-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 依赖于请求路径的解析表示,称为RequestPath用于访问解码的路径段值,并删除分号内容 (即 path 或 matrix 变量)。这意味着,与 Spring MVC 不同,您无需指明 是否解码请求路径,是否删除 路径匹配目的。spring-doc.cadn.net.cn

Spring WebFlux 也不支持后缀模式匹配,这与 Spring MVC 不同,在 Spring MVC 中,我们 也建议远离 依赖它。spring-doc.cadn.net.cn

阻止执行

WebFlux Java 配置允许您自定义 WebFlux 中的阻塞执行。spring-doc.cadn.net.cn

您可以通过提供 一AsyncTaskExecutor例如VirtualThreadTaskExecutor如下: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)
	}
}

默认情况下,其返回类型的控制器方法无法被配置的ReactiveAdapterRegistry被视为阻塞,但您可以设置自定义控制器 方法 predicate viaBlockingExecutionConfigurer.spring-doc.cadn.net.cn

WebSocket服务

WebFlux Java 配置声明了WebSocketHandlerAdapterbean 提供 支持调用 WebSocket 处理程序。这意味着剩下的所有工作都要做 order 来处理 WebSocket 握手请求的是将WebSocketHandler到 URL 通过SimpleUrlHandlerMapping.spring-doc.cadn.net.cn

在某些情况下,可能需要创建WebSocketHandlerAdapter带有 提供WebSocketService服务,该服务允许配置 WebSocket 服务器属性。 例如: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)
	}
}

高级配置模式

@EnableWebFlux进口DelegatingWebFluxConfiguration那:spring-doc.cadn.net.cn

对于高级模式,您可以删除@EnableWebFlux并直接从DelegatingWebFluxConfiguration而不是实现WebFluxConfigurer, 如下例所示:spring-doc.cadn.net.cn

@Configuration
public class WebConfig extends DelegatingWebFluxConfiguration {

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

	// ...
}

您可以将现有方法保留在WebConfig,但您现在也可以覆盖 Bean 声明 从基类中,并且仍然具有任意数量的其他WebMvcConfigurer上的 implementations 类路径。spring-doc.cadn.net.cn