Understanding Spring WebFlux’s DispatcherHandler and Request Flow

This article explains how Spring WebFlux uses the DispatcherHandler, HandlerMapping, HandlerAdapter, and various HandlerResultHandlers to process requests, configure special beans, and manage exceptions in a reactive backend environment.

Spring Full-Stack Practical Cases
Spring Full-Stack Practical Cases
Spring Full-Stack Practical Cases
Understanding Spring WebFlux’s DispatcherHandler and Request Flow

Overview

Similar to Spring MVC, Spring WebFlux is built around the front‑controller pattern. Its core handler, WebHandler , is implemented by DispatcherHandler , which provides shared algorithms for request processing while delegating actual work to configurable components, allowing flexible workflows.

Special Beans

DispatcherHandler discovers required delegate beans from the Spring context. It is itself a bean and implements ApplicationContextAware to access its context. When a bean named webHandler is declared, WebHttpHandlerBuilder finds it and assembles the request‑handling chain.

WebFlux Configuration

Typical WebFlux applications declare beans such as:

Bean named webHandler of type DispatcherHandler

WebFilter and WebExceptionHandler

Special DispatcherHandler bean

Other supporting beans

These beans are supplied to WebHttpHandlerBuilder to build the handling chain, as shown in the example below.

public class HttpHandlerAutoConfiguration {
  @Configuration(proxyBeanMethods = false)
  public static class AnnotationConfig {
    @Bean
    public HttpHandler httpHandler(ObjectProvider<WebFluxProperties> propsProvider) {
      // applicationContext method collects WebFilter and WebExceptionHandler
      // build method constructs HttpWebHandlerAdapter (implements HttpHandler) that wraps them
      HttpHandler httpHandler = WebHttpHandlerBuilder.applicationContext(this.applicationContext).build();
      WebFluxProperties properties = propsProvider.getIfAvailable();
      if (properties != null && StringUtils.hasText(properties.getBasePath())) {
        Map<String, HttpHandler> handlersMap = Collections.singletonMap(properties.getBasePath(), httpHandler);
        return new ContextPathCompositeHandler(handlersMap);
      }
      return httpHandler;
    }
  }
}

HandlerMapping

HandlerMapping maps a request to a handler based on various criteria (e.g., @RequestMapping annotations or RouterFunction beans). The first matching mapping is used.

HandlerAdapter

After a handler is found, a suitable HandlerAdapter invokes it and produces a HandlerResult . The adapter shields DispatcherHandler from the details of how the handler is invoked.

HandlerResultHandler

The HandlerResult is passed to a HandlerResultHandler to complete the response, either by writing directly or by rendering a view. Common implementations include:

ResponseEntityResultHandler – handles ResponseEntity returned from @Controller methods.

ServerResponseResultHandler – handles ServerResponse from functional endpoints.

ResponseBodyResultHandler – handles values from @ResponseBody or @RestController methods.

ViewResolutionResultHandler – resolves CharSequence, view names, models, etc.

Request Handling

Each HandlerMapping tries to find a matching handler; the first match wins.

If a handler is found, the appropriate HandlerAdapter executes it, producing a HandlerResult .

The HandlerResult is then processed by a HandlerResultHandler to generate the final response.

Exception Handling

If a handler fails or a HandlerResultHandler cannot process the result, an error function can modify the response before any data is written. In WebFlux, @ExceptionHandler methods in @Controller classes are supported via HandlerExceptionResolver , but @ControllerAdvice cannot handle exceptions that occur before a handler is selected; those must be handled by a WebExceptionHandler .

@RestControllerAdvice
public class PackControllerAdvice {
  @ExceptionHandler
  public ResponseEntity<String> handle(Exception ex) {
    ex.printStackTrace();
    return ResponseEntity.ok(ex.getMessage() + ", Advice");
  }
}
@Component
@Order(Ordered.HIGHEST_PRECEDENCE)
public class CustomWebExceptionHandler implements WebExceptionHandler {
  @Override
  public Mono<Void> handle(ServerWebExchange exchange, Throwable ex) {
    System.out.println("异常了: " + ex.getMessage());
    ServerHttpResponse response = exchange.getResponse();
    response.setStatusCode(HttpStatus.INTERNAL_SERVER_ERROR);
    response.getHeaders().add("ContentType", "text/html;charset=utf8");
    return response.writeWith(Mono.just(exchange.getResponse().bufferFactory().wrap("ERROR".getBytes(Charset.forName("UTF-8")))));
  }
}

End of article.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

WebFlux
Spring Full-Stack Practical Cases
Written by

Spring Full-Stack Practical Cases

Full-stack Java development with Vue 2/3 front-end suite; hands-on examples and source code analysis for Spring, Spring Boot 2/3, and Spring Cloud.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.