Spring Cloud Gateway学习笔记:DispatcherHandler的调用,filter链

今天的文章内容比较散,本来想搞明白请求是如何调到DispatcherHandler的,debug一通发现里面逻辑也太复杂了,全是Netty Reactor编程,这就无法啃了,留着后面去研究了。

下面文章解答下昨天留的两个下问题。

1. DispatcherHandler上层调用

从debug的调试来看,可以确认DispatcherHandler是在HttpWebHandlerAdapter#handle方法中调用的,因此我们可以进一步总结出SCG的调用链路:HttpWebHandlerAdapter --> DispatcherHandler --> RoutePredicateHandlerMapping --> FilteringWebHandler。HttpWebHandlerAdapter#handle源码如下,至于如何调进来这里得研究完Netty Reactor才知道了.

public Mono<Void> handle(ServerHttpRequest request, ServerHttpResponse response) {
        if (this.forwardedHeaderTransformer != null) {
            request = this.forwardedHeaderTransformer.apply(request);
        }

        ServerWebExchange exchange = this.createExchange(request, response);
        LogFormatUtils.traceDebug(logger, (traceOn) -> {
            return exchange.getLogPrefix() + this.formatRequest(exchange.getRequest()) + (traceOn ? ", headers=" + this.formatHeaders(exchange.getRequest().getHeaders()) : "");
        });
        // this.getDelegate().handle(exchange)就是调用了DispatcherHandler#handler
        Mono var10000 = this.getDelegate().handle(exchange).doOnSuccess((aVoid) -> {
            this.logResponse(exchange);
        }).onErrorResume((ex) -> {
            return this.handleUnresolvedError(exchange, ex);
        });
        response.getClass();
        return var10000.then(Mono.defer(response::setComplete));
    }

2、 Filter链路的调用逻辑

上一篇文章,我们知道filter最后是调用了DefaultGatewayFilterChain#filter,我们首先来看DefaultGatewayFilterChain类的代码

private static class DefaultGatewayFilterChain implements GatewayFilterChain {

		private final int index;

		private final List<GatewayFilter> filters;

		DefaultGatewayFilterChain(List<GatewayFilter> filters) {
			// filter列表,从FilteringWebHandler传进来
			this.filters = filters;
			// index代表当前执行filter列表的下标
			this.index = 0;
		}

		private DefaultGatewayFilterChain(DefaultGatewayFilterChain parent, int index) {
			this.filters = parent.getFilters();
			this.index = index;
		}

		public List<GatewayFilter> getFilters() {
			return filters;
		}

		@Override
		public Mono<Void> filter(ServerWebExchange exchange) {
			return Mono.defer(() -> {
				// 如果下标小于filter列表,代表列表的filter没有执行完,则继续执行后面的filter
				if (this.index < filters.size()) {
					// 依据下标获取当前需要执行的filter
					GatewayFilter filter = filters.get(this.index);
					// 新建一个filter链,并且把filter列表的下标加一,下一次就是执行列表后一个filter
					DefaultGatewayFilterChain chain = new DefaultGatewayFilterChain(this,
							this.index + 1);
					return filter.filter(exchange, chain);
				}
				else {
					// filter列表为空,则不做任务处理
					return Mono.empty(); // complete
				}
			});
		}
	}

上面代码得结合某一个具体的filter实现才能明白,选择RemoveCachedBodyFilter#filter来看下就可以明白filter链是如何工作的

	public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
		// doFially里的逻辑执行完则执行下一个filter,即调用chain.filter,就是通过这种调用链的方式来执行列表中所有filter
		return chain.filter(exchange).doFinally(s -> {
			Object attribute = exchange.getAttributes().remove(CACHED_REQUEST_BODY_ATTR);
			if (attribute != null && attribute instanceof PooledDataBuffer) {
				PooledDataBuffer dataBuffer = (PooledDataBuffer) attribute;
				if (dataBuffer.isAllocated()) {
					if (log.isTraceEnabled()) {
						log.trace("releasing cached body in exchange attribute");
					}
					dataBuffer.release();
				}
			}
		});
	}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值