今天的文章内容比较散,本来想搞明白请求是如何调到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();
}
}
});
}