Refine @EnableWebFlux docs for functional endpoints

@EnableWebFlux bootstraps both annotated controllers and functional
endpoints, so we need to be more explicit about which parts of the
configuration apply to which.

Issue: SPR-16360
This commit is contained in:
Rossen Stoyanchev 2018-01-11 11:55:37 -05:00
parent 8f6d3feaa0
commit 72e3c43375
4 changed files with 69 additions and 53 deletions

View File

@ -25,8 +25,11 @@ import java.lang.annotation.Target;
import org.springframework.context.annotation.Import;
/**
* Adding this annotation to an {@code @Configuration} class imports the Spring Web
* Reactive configuration from {@link WebFluxConfigurationSupport}, e.g.:
* Adding this annotation to an {@code @Configuration} class imports the Spring
* WebFlux configuration from {@link WebFluxConfigurationSupport} that enables
* use of annotated controllers and functional endpoints.
*
* <p>For example:
*
* <pre class="code">
* &#064;Configuration
@ -36,8 +39,8 @@ import org.springframework.context.annotation.Import;
* }
* </pre>
*
* <p>To customize the imported configuration implement
* {@link WebFluxConfigurer} and override individual methods as shown below:
* <p>To customize the imported configuration, implement
* {@link WebFluxConfigurer} and one or more of its methods:
*
* <pre class="code">
* &#064;Configuration
@ -46,33 +49,32 @@ import org.springframework.context.annotation.Import;
* public class MyConfiguration implements WebFluxConfigurer {
*
* &#064;Override
* public void addFormatters(FormatterRegistry formatterRegistry) {
* formatterRegistry.addConverter(new MyConverter());
* }
*
* &#064;Override
* public void configureMessageWriters(List&lt;HttpMessageWriter&lt;?&gt&gt messageWriters) {
* messageWriters.add(new MyHttpMessageWriter());
* }
*
* // ...
* }
* </pre>
*
* <p><strong>Note:</strong> only one {@code @Configuration} class may have the
* {@code @EnableWebFlux} annotation to import the Spring WebFlux configuration.
* There can however be multiple {@code @Configuration} classes implementing
* {@code WebFluxConfigurer} in order to customize the provided configuration.
* <p>Only one {@code @Configuration} class should have the {@code @EnableWebFlux}
* annotation in order to import the Spring WebFlux configuration. There can
* however be multiple {@code @Configuration} classes that implement
* {@code WebFluxConfigurer} that customize the provided configuration.
*
* <p>If {@link WebFluxConfigurer} does not expose some more advanced setting
* that needs to be configured consider removing the {@code @EnableWebFlux}
* annotation and extending directly from {@link WebFluxConfigurationSupport}
* or {@link DelegatingWebFluxConfiguration} if you still want to allow
* {@link WebFluxConfigurer} instances to customize the configuration.
* <p>If {@code WebFluxConfigurer} does not expose some setting that needs to be
* configured, consider switching to an advanced mode by removing the
* {@code @EnableWebFlux} annotation and extending directly from
* {@link WebFluxConfigurationSupport} or {@link DelegatingWebFluxConfiguration} --
* the latter allows detecting and delegating to one or more
* {@code WebFluxConfigurer} configuration classes.
*
* @author Brian Clozel
* @author Rossen Stoyanchev
* @since 5.0
* @see WebFluxConfigurer
* @see WebFluxConfigurationSupport
* @see DelegatingWebFluxConfiguration
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)

View File

@ -28,7 +28,7 @@ import org.springframework.web.reactive.result.method.annotation.ArgumentResolve
/**
* Defines callback methods to customize the configuration for WebFlux
* applications enabled via {@code @EnableWebFlux}.
* applications enabled via {@link EnableWebFlux @EnableWebFlux}.
*
* <p>{@code @EnableWebFlux}-annotated configuration classes may implement
* this interface to be called back and given a chance to customize the
@ -38,18 +38,25 @@ import org.springframework.web.reactive.result.method.annotation.ArgumentResolve
* @author Brian Clozel
* @author Rossen Stoyanchev
* @since 5.0
* @see WebFluxConfigurationSupport
* @see DelegatingWebFluxConfiguration
*/
public interface WebFluxConfigurer {
/**
* Configure how the content type requested for the response is resolved.
* Configure how the content type requested for the response is resolved
* when handling reqests with annotated controllers.
* @param builder for configuring the resolvers to use
*/
default void configureContentTypeResolver(RequestedContentTypeResolverBuilder builder) {
}
/**
* Configure cross origin requests processing.
* Configure "global" cross origin request processing.
* <p>The configured readers and writers will apply to all requests including
* annotated controllers and functional endpoints. Annotated controllers can
* further declare more fine-grained configuration via
* {@link org.springframework.web.bind.annotation.CrossOrigin @CrossOrigin}.
* @see CorsRegistry
*/
default void addCorsMappings(CorsRegistry registry) {
@ -57,8 +64,9 @@ public interface WebFluxConfigurer {
/**
* Configure path matching options.
*
* {@code HandlerMapping}s with path matching options.
* <p>The configured path matching options will be used for mapping to
* annotated controllers and also
* {@link #addResourceHandlers(ResourceHandlerRegistry) static resources}.
* @param configurer the {@link PathMatchConfigurer} instance
*/
default void configurePathMatching(PathMatchConfigurer configurer) {
@ -72,7 +80,7 @@ public interface WebFluxConfigurer {
}
/**
* Configure resolvers for custom controller method arguments.
* Configure resolvers for custom {@code @RequestMapping} method arguments.
* @param configurer to configurer to use
*/
default void configureArgumentResolvers(ArgumentResolverConfigurer configurer) {
@ -80,6 +88,8 @@ public interface WebFluxConfigurer {
/**
* Configure custom HTTP message readers and writers or override built-in ones.
* <p>The configured readers and writers will be used for both annotated
* controllers and functional endpoints.
* @param configurer the configurer to use
*/
default void configureHttpMessageCodecs(ServerCodecConfigurer configurer) {
@ -87,7 +97,7 @@ public interface WebFluxConfigurer {
/**
* Add custom {@link Converter}s and {@link Formatter}s for performing type
* conversion and formatting of controller method arguments.
* conversion and formatting of annotated controller method arguments.
*/
default void addFormatters(FormatterRegistry registry) {
}
@ -96,6 +106,8 @@ public interface WebFluxConfigurer {
* Provide a custom {@link Validator}.
* <p>By default a validator for standard bean validation is created if
* bean validation api is present on the classpath.
* <p>The configured validator is used for validating annotated controller
* method arguments.
*/
@Nullable
default Validator getValidator() {
@ -103,8 +115,9 @@ public interface WebFluxConfigurer {
}
/**
* Provide a custom {@link MessageCodesResolver} to use for data binding instead
* of the one created by default in {@link org.springframework.validation.DataBinder}.
* Provide a custom {@link MessageCodesResolver} to use for data binding in
* annotated controller method arguments instead of the one created by
* default in {@link org.springframework.validation.DataBinder}.
*/
@Nullable
default MessageCodesResolver getMessageCodesResolver() {
@ -112,14 +125,11 @@ public interface WebFluxConfigurer {
}
/**
* Configure view resolution for processing the return values of controller
* methods that rely on resolving a
* {@link org.springframework.web.reactive.result.view.View} to render
* the response with. By default all controller methods rely on view
* resolution unless annotated with {@code @ResponseBody} or explicitly
* return {@code ResponseEntity}. A view may be specified explicitly with
* a String return value or implicitly, e.g. {@code void} return value.
* @see ViewResolverRegistry
* Configure view resolution for rendering responses with a view and a model,
* where the view is typically an HTML template but could also be based on
* an HTTP message writer (e.g. JSON, XML).
* <p>The configured view resolvers will be used for both annotated
* controllers and functional endpoints.
*/
default void configureViewResolvers(ViewResolverRegistry registry) {
}

View File

@ -205,20 +205,21 @@ The returned `HttpHandler` can then be used with a number of servers adapters by
A more advanced option is to run with a
<<web-reactive.adoc#webflux-dispatcher-handler,DispatcherHandler>>-based setup through the
<<web-reactive.adoc#webflux-config>> which uses Spring configuration to declare the
components process requests. The WebFlux Java config declares the following components
related to functional endpoints:
components quired to process requests. The WebFlux Java config declares the following
infrastructure components to support functional endpoints:
* `RouterFunctionMapping` -- this detects one or more `RouterFunction<?>` beans in the
Spring configuration, combines them via `RouterFunction.andOther`, and routes requests to
the resulting, composed `RouterFunction`.
* `HandlerFunctionAdapter` -- simple adapter to invoke a `HandlerFunction` selected to
handle a request.
* `ServerResponseResultHandler` -- invokes the `writeTo` method of the `ServerResponse`
returned by the `HandlerFunction`.
* `RouterFunctionMapping` -- detects one or more `RouterFunction<?>` beans in the Spring
configuration, combines them via `RouterFunction.andOther`, and routes requests to the
resulting composed `RouterFunction`.
* `HandlerFunctionAdapter` -- simple adapter that allows the `DispatcherHandler` to invoke
a `HandlerFunction` that was mapped to a request.
* `ServerResponseResultHandler` -- handles the result from the invocation of a
`HandlerFunction` by invoking the `writeTo` method of the `ServerResponse`.
The above allows functional endpoints to fit within the `DispatcherHandler` request
processing lifecycle, and potentially to run side by side with annotated controllers, if
any are declared. This is also the mechanism used in the Spring Boot WebFlux starter.
The above components allow functional endpoints to fit within the `DispatcherHandler` request
processing lifecycle, and also potentially run side by side with annotated controllers, if
any are declared. It is also how functional endpoints are enabled the Spring Boot WebFlux
starter.
Below is example WebFlux Java config (see
<<web-reactive.adoc#webflux-dispatcher-handler,DispatcherHandler>> for how to run):

View File

@ -1098,13 +1098,16 @@ include::webflux-functional.adoc[leveloffset=+1]
== WebFlux Java Config
[.small]#<<web.adoc#mvc-config,Same in Spring MVC>>#
The WebFlux Java config provides default configuration suitable for most applications along
with a configuration API to customize it. For more advanced customizations, not available in
the configuration API, see <<webflux-config-advanced-java>>.
The WebFlux Java config declares components required to process requests with annotated
controllers or functional endpoints, and it offers an API to customize the configuration.
That means you do not need to understand the underlying beans created by the Java config
but, if you want to, it's very easy to see them in `WebFluxConfigurationSupport` or read more
what they are in <<webflux-special-bean-types>>.
For more advanced customizations, not available in the configuration API, it is also
possible to gain full control over the configuration through the
<<webflux-config-advanced-java>>.
You do not need to understand the underlying beans created by the Java config, but it's
easy to seem them in `WebFluxConfigurationSupport`, and if you want to learn more, see
<<webflux-special-bean-types>>.