Skip to content

Latest commit

 

History

History
131 lines (116 loc) · 5.6 KB

springwebflux-source-note.md

File metadata and controls

131 lines (116 loc) · 5.6 KB

资料

Spring WebFlux 官方文档

响应式API官方文档

示例代码

源码分析

@EnableWebFlux

/** * 思路 SpringMVC 可以说是类似,只不过注册的是 ServletHttpHandlerAdapter 而不是 DispatcherServlet * * @EnableWebFlux 主要是通过 @Bean 注册了 RequestMappingHandlerAdapter、RequestMappingHandlerMapping、DispatcherHandler * 最主要是 DispatcherHandler ,它是 WebHandler 类型的 bean ,是 webflux 处理请求的入口( Servlet 会将请求委托给 WebHandler 处理)。 * DispatcherHandler 会依赖 HandlerAdapter、HandlerMapping 处理收到的请求,和 DispatcherServlet 的处理逻辑一致,只不过是少了 * HandlerExceptionResolver 和 ViewResolver 而已。 * * 注:是支持 @Controller、@RestController、@RequestMapping 来定义请求的处理逻辑 * * */

AbstractReactiveWebInitializer

建议先看 SpringMVC 一下独立web应用的启动流程

/** * 对于独立Web应用的场景,spring-web.jar 中提供了 AbstractReactiveWebInitializer 这个抽象类,定义了将 Servlet 注册到 web 容器的逻辑 * {@link AbstractReactiveWebInitializer#onStartup(ServletContext)} * * // 对 WebHandler 层层装饰 * FilteringWebHandler 代理 WebHandler (默认配置的是 DispatcherHandler), 增加了使用 WebFilter 的逻辑 * ExceptionHandlingWebHandler 代理 FilteringWebHandler, 增加了使用 WebExceptionHandler 的逻辑 * HttpWebHandlerAdapter 代理 ExceptionHandlingWebHandler, 增加了 自定义 request、装饰request和response 的逻辑 * 最终暴露出去的是 HttpWebHandlerAdapter *  * WebHandler decorated = new FilteringWebHandler( DispatcherHandler, List<WebFilter> ); * decorated = new ExceptionHandlingWebHandler(decorated, List<WebExceptionHandler> ); * HttpWebHandlerAdapter adapted = new HttpWebHandlerAdapter(decorated); * * // 依赖 WebHandler 生成 Servlet * ServletHttpHandlerAdapter servlet = new ServletHttpHandlerAdapter(adapted); * * // 将 servlet 注册到 web容器中 * servletContext.addServlet(servletName, servlet) * * PS: 很简单吧。有了 SpringMVC 的基础再看 Spring-WebFlux 实在是太轻松了,只不过使用的 响应式API不大懂 * * 注:用到了响应式的API,我也没接触过,用到在了解吧,暂时弄明白流程就好了。 * */

ServletHttpHandlerAdapter#service

/** * ServletHttpHandlerAdapter 的执行流程 * {@link ServletHttpHandlerAdapter#service(ServletRequest, ServletResponse)} * 1. 开启异步 * AsyncContext asyncContext = request.startAsync(); * * 2. 注册 监听器。完成请求时会回调监听器的生命周期方法 * asyncContext.addListener(new HttpHandlerAsyncListener(...)) * * 3. 委托给 HttpWebHandlerAdapter 执行 * httpHandler.handle(httpRequest, httpResponse).subscribe(subscriber); * * HttpWebHandlerAdapter 大致的执行逻辑如下: * {@link HttpWebHandlerAdapter#handle(ServerHttpRequest, ServerHttpResponse)} * 1. 使用 ForwardedHeaderTransformer 用来对 request 进行自定义 * request = this.forwardedHeaderTransformer.apply(request); * * 2. 构造出 ServerWebExchange * ServerWebExchange exchange = createExchange(request, response); * * 3. 委托给 ExceptionHandlingWebHandler 执行 * {@link ExceptionHandlingWebHandler#handle(ServerWebExchange)} *  * 3.1 委托给 FilteringWebHandler 执行拿到返回值 * {@link FilteringWebHandler#handle(ServerWebExchange)} * 其实就是迭代执行 WebFilter,然后再委托给 DispatcherHandler 执行 * * 3.2 处理异常信息 * // 遍历 exceptionHandlers 处理异常 * for (WebExceptionHandler handler : this.exceptionHandlers) { * completion = completion.onErrorResume(ex -> handler.handle(exchange, ex)); * } * */

DispatcherHandler#handle

@OverridepublicMono<Void> handle(ServerWebExchangeexchange) { if (this.handlerMappings == null) { returncreateNotFoundError(); } // 针对 预检 请求的处理if (CorsUtils.isPreFlightRequest(exchange.getRequest())) { returnhandlePreFlight(exchange); } /** * 和 SpringMVC 是类似的。 * * 1. 使用 {@link HandlerMapping#getHandler(ServerWebExchange)} 得到 handler * 2. 遍历 {@link HandlerAdapter#supports(Object)} 找到适配的,就用来执行 handler * 3. 遍历 {@link HandlerResultHandler#supports(HandlerResult)} 找到适配的,就用来处理 返回结果 *  * Tips: * - 使用 @EnableWebFlux 会注册 RequestMappingHandlerMapping、RequestMappingHandlerAdapter 是用来处理 * @Controller、@RequestMapping、@InitBinder、@SessionAttribute、@ModelAttribute 的,功能和SpringMVC是一致的 *  * - 会注册 ViewResolutionResultHandler 是用来支持 视图的 * */returnFlux.fromIterable(this.handlerMappings) // concatMap 会收集不是 Mono.Empty() 的内容 组成 Flux .concatMap(mapping -> mapping.getHandler(exchange)) .next() .switchIfEmpty(createNotFoundError()) .flatMap(handler -> invokeHandler(exchange, handler)) .flatMap(result -> handleResult(exchange, result)); }
close