概述与SpringMVC类似,SpringWebFlux是围绕前端控制器模式设计的,其中核心处理程序WebHandler实现DispatcherHandler提供共享算法进行请求处理,而实际工作则委托给一个可配置的Component执行。该模型非常灵活,支持多种工作流程。DispatcherHandler从Spring配置中发现所需的委托组件。它本身也被设计为一个bean,并实现ApplicationContextAware以访问它运行的上下文。如果DispatcherHandler是用webHandler的bean名称声明的,WebHttpHandlerBuilder将找到它,它将按照webHandlerAPI中的描述将请求处理链放在一起。WebFlux应用程序中的Spring配置通常包含:DispatcherHandlerWebFilter,bean名称为webHandler和WebExceptionHandlerDispatcherHandler特殊bean其他配置提供给WebHttpHandlerBuilder以构建处理链,如下例所示:publicclassHttpHandlerAutoConfiguration{@Configuration(proxyBeanMethods=false)publicstaticclassAnnotationConfig{@BeanpublicHttpHandlerhttpHandler(ObjectProviderpropsProvider){//applicationContext方法将在容器中收集WebFilter和WebExceptionHandler//build方法构建HttpWebHandlerAdapter(实现HttpHandler),//包装WebFilter和WebExceptionHandler集合HttpHandlerhttpHandler=WebHttpHandlerBuilder.applicationContext(this.applicationContext).build();WebFluxProperties属性=propsProvider.getIfAvailable();if(properties!=null&&StringUtils.hasText(properties.getBasePath())){MaphandlersMap=Collections.singletonMap(properties.getBasePath(),httpHandler);返回新的ContextPathCompositeHandler(handlersMap);}返回httpHandler;}}}SpecialBeanDispatcherHandler委托一个特殊的bean来处理请求并提供适当的响应。所谓“特殊bean”是指实现了WebFlux框架指定的Spring管理的对象实例。这些bean通常是内置的,但您可以自定义、扩展或替换它们的属性。HandlerMapping将请求映射到处理程序。映射基于一些标准,其细节因HandlerMapping实现而异——带注释的控制器、简单的URL模式映射等。例如:@RequestMapping注解的Controller或RouterFunction类型的bean由不同的HandlerMapping处理。HandlerAdapter帮助DispatcherHandler调用映射到请求的处理程序,而不管实际调用处理程序的方式如何。例如,调用带注解的控制器需要解析注解。HandlerAdapter的主要目的是保护DispatcherHandler免受这些细节的影响。简单的说,不同的HandlerAdapter处理不同的HandlerMapping返回的不同的Handler对象,比如:RequestMappingHandlerMapping返回的HandlerMethod,RouterFunctionMapping返回的HandlerFunction。HandlerResultHandler处理处理程序调用的结果并完成响应。WebFlux配置应用程序可以声明处理请求所需的底层beans(在WebHandlerAPI和DispatcherHandler下列出)。但是,在大多数情况下,WebFlux配置是最好的起点。它声明所需的beans并提供更高级别的配置回调API来对其进行自定义。请求处理DispatcherHandler通过以下方式处理请求:要求每个HandlerMapping找到匹配的处理程序,并使用第一个匹配项。如果找到处理程序,它将通过适当的HandlerAdapter运行,它将执行返回的值公开为HandlerResult。HandlerResult被提供给适当的HandlerResultHandler以通过直接写入响应或用视图渲染它来完成处理。结果处理调用处理程序的返回值通过HandlerAdapter包装为HandlerResult,以及一些额外的上下文,并传递给第一个声称支持它的HandlerResultHandler。下表列出了可用的HandlerResultHandler实现,所有这些实现都在WebFluxConfig中声明:ResponseEntityResultHandler返回:ResponseEntity,通常来自@Controller实例。ServerResponseResultHandler返回值:ServerResponse,通常来自功能端点。ResponseBodyResultHandler返回值:处理来自@ResponseBody方法或@RestController类的返回值。ViewResolutionResultHandler返回值:CharSequence、视图、模型、地图、渲染或任何其他对象都被视为模型属性。异常处理从HandlerAdapter返回的HandlerResult可以公开基于某些处理程序特定机制的错误处理函数。当处理程序(例如@Controller)调用失败时调用此错误函数。通过HandlerResultHandler处理处理程序返回值失败。只要错误信号发生在从处理程序返回的响应类型生成任何数据项之前,错误函数就可以更改响应(例如,更改为错误状态)。这就是支持@Controller类中的@ExceptionHandler方法的方式。相比之下,SpringMVC中的支持也是建立在HandlerExceptionResolver之上的。注意:在WebFlux中,@ControllerAdvice不能用于处理在选择处理程序之前发生的异常。@RestControllerAdvicepublicclassPackControllerAdvice{@ExceptionHandlerpublicResponseEntityhandle(Exceptionex){ex.printStackTrace();返回ResponseEntity.ok(ex.getMessage()+",Advice");注意:这不能处理调用处理程序之前的任何异常,处理程序之前的异常应该由WebExceptionHandler处理,以下异常处理程序将处理,由WebFilter实例和异常链接到目标WebHandle。@Component@Order(Ordered.HIGHEST_PRECEDENCE)publicclassCustomWebExceptionHandlerimplementsWebExceptionHandler{@OverridepublicMonohandle(ServerWebExchangeexchange,Throwableex){System.out.println("Exception:"+ex.getMessage());//把error传过去,后面的onErrorResume可以继续执行;如果通过,下一个处理程序将是DefaultErrorWebExceptionHandler//returnMono.error(ex);//exchange.getResponse()//返回Mono.error(ex);//下面不会传递异常,直接输出错误信息ServerHttpResponseresponse=exchange.getResponse();response.setStatusCode(HttpStatus.INTERNAL_SERVER_ERROR);response.getHeaders().add("ContentType","text/html;charset=utf8");返回response.writeWith(Mono.just(exchange.getResponse().bufferFactory().wrap("ERROR".getBytes(Charset.forName("UTF-8")))));}}