SpringWebFlux核心处理组件DispatcherHandler
环境:SpringBoot2.4.12
请先阅读:
Spring WebFlux使用函数式编程之HandlerFunction(1)
Spring WebFlux使用函数式编程之RouterFunction(2)
Spring WebFlux请求处理流程
一文带你彻底理解Spring WebFlux的工作原理 Reactor响应式编程(Flux、Mono)基本用法
概述
与Spring MVC类似,Spring WebFlux是围绕前端控制器模式设计的,其中核心处理程序 WebHandler 的实现 DispatcherHandler 为请求处理提供共享算法,而实际工作由可配置的委托组件执行。该模型非常灵活,支持多种工作流。
DispatcherHandler 从Spring配置中发现所需的委托组件。它本身也被设计为bean,并实现ApplicationContextAware 以访问它运行的上下文。如果DispatcherHandler 是用webHandler的bean名称声明的,那么WebHttpHandlerBuilder 会发现它,它会将请求处理链组合在一起,如webHandler API中所述。
WebFlux应用程序中的Spring配置通常包含:bean名称为webHandler的DispatcherHandler WebFilter 和WebExceptionHandler DispatcherHandler 特殊bean其它
配置被提供给WebHttpHandlerBuilder 以构建处理链,如下例所示:public class HttpHandlerAutoConfiguration { @Configuration(proxyBeanMethods = false) public static class AnnotationConfig { @Bean public HttpHandler httpHandler(ObjectProvider propsProvider) { // applicationContext方法中会收集容器中WebFilter和WebExceptionHandler // build方法中构建了HttpWebHandlerAdapter(实现了HttpHandler),该对象中 // 包装了WebFilter和WebExceptionHandler集合 HttpHandler httpHandler = WebHttpHandlerBuilder.applicationContext(this.applicationContext).build(); WebFluxProperties properties = propsProvider.getIfAvailable(); if (properties != null && StringUtils.hasText(properties.getBasePath())) { Map handlersMap = Collections.singletonMap(properties.getBasePath(), httpHandler); return new ContextPathCompositeHandler(handlersMap); } return httpHandler; } } }特殊一样的Bean
DispatcherHandler 委托特殊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配置
应用程序可以声明处理请求所需的基础bean(列在Web Handler API和DispatcherHandler下面)。但是,在大多数情况下,WebFlux配置是最好的起点。它声明所需的bean,并提供更高级别的配置回调API来自定义它。请求处理
DispatcherHandler 处理请求的方式如下:每个HandlerMapping 被要求找到一个匹配的处理程序,并使用第一个匹配。如果找到处理程序,则通过适当的HandlerAdapter 运行它,它将从执行中返回的值公开为HandlerResult 。HandlerResult 被提供给适当的HandlerResultHandler ,以通过直接写入响应或使用视图进行渲染来完成处理。结果处理
调用处理程序的返回值通过HandlerAdapter 被包装为HandlerResult ,以及一些附加的上下文,并传递给声称支持它的第一个HandlerResultHandler 。下表列出可用的HandlerResultHandler 实现,所有这些实现都在WebFlux Config中声明:ResponseEntityResultHandler
返回值:ResponseEntity , 通常来自 @Controller 实例。 ServerResponseResultHandler
返回值:ServerResponse ,通常来自功能端点。ResponseBodyResultHandler
返回值:处理来自@ResponseBody 方法或@RestController 类的返回值。ViewResolutionResultHandler
返回值:CharSequence、视图、模型、映射、渲染或任何其他对象都被视为模型属性。异常处理
从HandlerAdapter 返回的HandlerResult 可以基于某些特定于处理程序的机制公开用于错误处理的函数。在以下情况下调用此错误函数:处理程序(例如,@Controller)调用失败。通过HandlerResultHandler 处理处理程序返回值失败。
只要错误信号发生在从处理程序返回的响应类型产生任何数据项之前,error函数就可以更改响应(例如,更改为错误状态)。
这就是如何支持@Controller类中的@ExceptionHandler方法。相比之下,Spring MVC中的支持也是建立在 HandlerExceptionResolver 上的。注意:在WebFlux中,不能使用 @ControllerAdvice 来处理在选择处理程序之前发生的异常。 @RestControllerAdvice public class PackControllerAdvice { @ExceptionHandler public ResponseEntity handle(Exception ex) { ex.printStackTrace(); return ResponseEntity.ok(ex.getMessage() + ", Advice"); } }
注意:这个不能处理调用处理程序之前的任何异常,处理程序之前的异常应该由WebExceptionHandler 来处理
下面的异常处理句柄将会处理,由WebFilter 实例链和目标WebHandle 的异常。@Component @Order(Ordered.HIGHEST_PRECEDENCE) public class CustomWebExceptionHandler implements WebExceptionHandler { @Override public Mono handle(ServerWebExchange exchange, Throwable ex) { System.out.println("异常了: " + ex.getMessage()) ; // 将错误传递下去,后面的onErrorResume还可以继续执行;如果传递,那么下一个处理器将会是DefaultErrorWebExceptionHandler // return Mono.error(ex) ; // exchange.getResponse() // return Mono.error(ex) ; // 下面不传递异常了,直接输出错误信息 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"))))) ; } }
完毕!!!
Spring中Aware接口实现原理解析
Spring Cloud Nacos 开启权限验证
Spring Cloud Nacos配置中心实现原理
Spring IOC容器对Bean实例化的过程详解源码分析
使用Spring Boot Admin实时监控你的系统
Spring注解@Qualifier这种用法你知道吗?
Spring AOP切入点类型及系统提供的非常常用的切入点
Spring Cloud Gateway应用详解1之谓词
2022孩子带给我的感动我的生活也是头条孩子刚过十岁生日,这一年明显感觉孩子变懂事很多。不管是学习方面,还是日常生活自理能力,都让我看到有很大的进步!每天早上,不用闹钟,也不用叫小妞起床,她基本都是到七点
被许志安绿,顶着天后粉丝的压力保全前女友,隐忍至今终于报仇马国明宣布和女友汤洛雯订婚传出喜讯,这是作为2023年娱乐圈第二件喜事了。不得不说马国明真的是因祸得福,现女友汤洛雯父亲是著名演员汤镇宗,叔叔是汤镇业,而且本人是伦敦大学的高材生,
网曝何炅双亲在近日去世,他因为工作错过葬礼,在晚会上泪流满面12月31日,湖南卫视跨年晚会上,出现了主持人何炅泪流满面的一幕,随后在网络上成为了话题。2022年注定是不平凡的一年,临近年底的时候,全国疫情政策放宽,很多国人都先后阳了,有不少
林心如肉眼可见的老,46岁穿卡通毛衣聚会,10倍滤镜大肉鼻都歪了毛衣可以让人温柔舒适的过冬,因此在秋冬季节必定少不了它的身影,不过随着潮流的发展,毛衣这件单品的变化真的是越来越大,除了款式变得丰富之外,在穿衣方式上,也是既可以当作内搭,也能拿来
广州猪肉价格连降六周,蔬菜价格上涨1月5日,记者从广州市发展和改革委员会获悉,12月26日1月1日,广州主要民生商品价格涨跌互现。蔬菜价格连续第五周上涨,猪肉价格连续第六周下跌,鸡蛋价格小幅下跌,水产品价格变化不大
二次感染来袭,建议中老年人少吃猪肉羊肉,多吃5样,助力恢复眼瞅着春节的脚步越来越近了,我们即将迎来返乡高潮,此时大家心中并没有往年的喜悦之情,相反多了一些担忧,因为彼此都很担心二次感染,尤其是对于中老年人来说,这个时候要格外小心。阳过之后
色香味俱全!来马尾名城中心过元旦啦2022年12月31日晚,由马尾区商务局马尾区文化体育和旅游局等联合主办的2022马尾八闽美食嘉年华暨2023马尾区美食文化旅游节在名城中心盛大开幕,区领导陈雪霞参加活动。晚7时,
进入腊月了,抢头福吃豆腐,多吃这3样美食,兔年有福又富足日子过的飞快,一眨眼就进入了腊月,马上就要迎新年了。腊月里有着很多的风俗讲究,就比如民间讲究推磨做豆腐,吃豆腐,据传说是因为腊月是玉帝考察民间的日子,人们为了表现勤劳,希望玉帝能多
重庆巨巨巨拉丝的芝士玉米瀑布!奶香味绝了!我也吃到拉丝芝士玉米啦!!超长瀑布!爆能拉丝!奶香味巨浓!芝士脑袋根本顶不住啊啊啊!我是一家火锅店吃到的!还在他家吃到了荷包蛋红糖汤圆!热呼呼的冬天吃真的巨温暖!汤圆糯叽叽的,里面
学数数我们每天都要反复上下楼好几次,每次乘坐电梯时都要按下自己楼层电梯号或一楼的电梯号的按钮。我就通过带着孙女乘坐电梯教会了孩子认识并能熟练地数100以内数字。首先,我先从自己居住的楼层
孕妇在出租车上生产,非常时期非常守护1月5日早晨942分,一辆出租车冲到公利医院大门入口,一名男乘客伸出头来我老婆把娃生车上了,怎么办?保安立刻通知急诊,并指点司机把车直接开到急诊大门口。急诊接到电话,立刻一键启动,