这是我参与11月更文挑战的第25天,活动详情查看:2021最后一次更文挑战
本系列代码地址:github.com/JoJoTec/spr…
我们继续分析上一节提到的 WebHandler
,经过将请求封装成 ServerWebExchange 的 HttpWebHandlerAdapter 之后,请求会经过 ExceptionHandlingWebHandler
全局 Web 处理异常处理器的接入点 - ExceptionHandlingWebHandler
之前有网友私信问过笔者,如何给 Spring Cloud Gateway 加全局异常处理器,其实和给基于 Spring-Flux 的异步 Web 服务加是一样的,都是通过实现并注册一个 WebExceptionHandler
Bean:
1 | kotlin复制代码public interface WebExceptionHandler { |
这些 Bean,就是在 ExceptionHandlingWebHandler 被加入到整个请求处理链路中的:
ExceptionHandlingWebHandler.java
1 | ini复制代码@Override |
从源码可以看出,这里将每个 WebExceptionHandler
作为 Mono 的异常处理 onErrorResume
加入了链路。onErrorResume
的意思是如果链路前面发生异常,则在这里捕获住异常同时调用 handler.handle(exchange, ex)
进行处理,如果使用阻塞代码理解,就相当于:
1 | kotlin复制代码try { |
这里我们看到有多个 WebExceptionHandler
,都会在链路后面追加 onErrorResume
,其实就相当于:
1 | less复制代码completion.onErrorResume(ex -> webExceptionHandler1.handle(exchange, ex)).onErrorResume(ex -> webExceptionHandler2.handle(exchange, ex)).onErrorResume(ex -> webExceptionHandler3.handle(exchange, ex))... |
转换成阻塞代码理解,其实就是:
1 | kotlin复制代码try { |
当 WebExceptionHandler 可以处理这个异常的时候,他的 handle
方法会返回一个真正的响应,否则会返回异常,例如:
1 | scss复制代码public class WebExceptionHandler1 implements WebExceptionHandler { |
转换成同步代码去理解其实就是:
1 | scss复制代码if (ex instanceof ResponseStatusException) { |
如果大家想封装自己统一的错误响应,可以通过实现这个接口进行实现。
DefaultWebFilterChain 的链路起点 - FilteringWebHandler
接下来进入 FilteringWebHandler,注意是 org.springframework.web.server.handler.FilteringWebHandler
而不是 Spring Cloud Gateway 的 org.springframework.cloud.gateway.handler.FilteringWebHandler
。在这里,会将上下文中载入的 WebFilter 拼接成 DefaultWebFilterChain
,然后调用其 filter 方法:
1 | kotlin复制代码private final DefaultWebFilterChain chain; |
Spring Cloud Gateway 的 FilteringWebHandler, 它是 Spring Cloud Gateway 的处理请求业务的起点。在这里我们即将进入整个 Spring Cloud Gateway 的 Filter 链路,包括每个路径自己的 GatewayFilter
以及全局的 GlobalGatewayFilter
,都是在这里开始被处理组装成完整调用链路的。我们后面还会提到
由于我们的项目依赖中包含了 Spring Cloud Sleuth 以及 Prometheus 的依赖,所以我们这里的 WebFilter 会包括三个:
org.springframework.boot.actuate.metrics.web.reactive.server.MetricsWebFilter
:添加 Prometheus 相关依赖之后,会有这个 MetricsWebFilter,用于记录请求处理耗时,采集相关指标。org.springframework.cloud.sleuth.instrument.web.TraceWebFilter
:添加 Spring Cloud Sleuth 相关依赖之后,会有这个 TraceWebFilter。org.springframework.cloud.gateway.handler.predicate.WeightCalculatorWebFilter
:Spring Cloud Gateway 路由权重相关配置功能相关实现类,这个我们这里不关心。
其具体流程,我们在下一节中继续详细分析。
微信搜索“我的编程喵”关注公众号,每日一刷,轻松提升技术,斩获各种offer:
本文转载自: 掘金