ReactorHttpHandlerAdapter
请求的入口在ReactorHttpHandlerAdapter#apply
, SpringWeb底层采用Netty作为网络框架,所以这里第一步先将Netty的请求转换为Reactor的请求。
public Mono<Void> apply(HttpServerRequest request, HttpServerResponse response) {
NettyDataBufferFactory bufferFactory = new NettyDataBufferFactory(response.alloc());
ReactorServerHttpRequest adaptedRequest;
Object adaptedResponse;
try {
// 将Netty的request和response转换为reactive包下对应的类
adaptedRequest = new ReactorServerHttpRequest(request, bufferFactory);
adaptedResponse = new ReactorServerHttpResponse(response, bufferFactory);
} catch (URISyntaxException var7) {
if (logger.isWarnEnabled()) {
logger.warn("Invalid URL for incoming request: " + var7.getMessage());
}
response.status(HttpResponseStatus.BAD_REQUEST);
return Mono.empty();
}
if (adaptedRequest.getMethod() == HttpMethod.HEAD) {
adaptedResponse = new HttpHeadResponseDecorator((ServerHttpResponse)adaptedResponse);
}
return this.httpHandler.handle(adaptedRequest, (ServerHttpResponse)adaptedResponse).doOnError((ex) -> {
logger.error("Handling completed with error", ex);
}).doOnSuccess((aVoid) -> {
logger.debug("Handling completed with success");
});
}
之后由HttpWebHandlerAdapter#handle
构造请求上下文exchange用于后续执行过滤链。
public Mono<Void> handle(ServerHttpRequest request, ServerHttpResponse response) {
// 构造请求上下文exchange贯穿整个请求流程
ServerWebExchange exchange = this.createExchange(request, response);
Mono var10000 = this.getDelegate().handle(exchange).onErrorResume((ex) -> {
return this.handleFailure(request, response, ex);
});
response.getClass();
return var10000.then(Mono.defer(response::setComplete));
}
DefaultWebFilterChain
DefaultWebFilterChain#filter
是SpringWeb中的类,这里和普通SpringWeb程序一样,执行所有Spring Web过滤器
public Mono<Void> filter(ServerWebExchange exchange) {
return Mono.defer(() -> {
if (this.index < this.filters.size()) {
WebFilter filter = this.filters.get(this.index);
WebFilterChain chain = new DefaultWebFilterChain(this, this.index + 1);
return filter.filter(exchange, chain);
}
else {
return this.handler.handle(exchange);
}
});
}
DispatcherHandler
由org.springframework.web.reactive.DispatcherHandler#handle
继续处理请求, DispatcherHandler在SpringMVC包里也有, 这也是为什么使用Springcloud Gateway要替换掉SpringMVC的依赖。
public Mono<Void> handle(ServerWebExchange exchange) {
if (logger.isDebugEnabled()) {
ServerHttpRequest request = exchange.getRequest();
logger.debug("Processing " + request.getMethodValue() + " request for [" + request.getURI() + "]");
}
if (this.handlerMappings == null) {
return Mono.error(HANDLER_NOT_FOUND_EXCEPTION);
}
return Flux.fromIterable(this.handlerMappings)
// 按顺序获取handler
.concatMap(mapping -> mapping.getHandler(exchange))
.next()
.switchIfEmpty(Mono.error(HANDLER_NOT_FOUND_EXCEPTION))
// 无序遍历所有HandlerAdapter,找到对应的HandlerAdapter执行Handler
.flatMap(handler -> invokeHandler(exchange, handler))
// 无序遍历所有HandlerResultHandler, 找到对应的HandlerResultHandler返回
.flatMap(result -> handleResult(exchange, result));
}
RoutePredicateHandlerMapping
上一步获取handler, 会进入RoutePredicateHandlerMapping#getHandlerInternal
,
protected Mono<?> getHandlerInternal(ServerWebExchange exchange) {
// 设置 GATEWAY_HANDLER_MAPPER_ATTR 为 RoutePredicateHandlerMapping
exchange.getAttributes().put(GATEWAY_HANDLER_MAPPER_ATTR, getClass().getSimpleName());
return lookupRoute(exchange) // 匹配 Route
.flatMap((Function<Route, Mono<?>>) r -> { // 返回 FilteringWebHandler
if (logger.isDebugEnabled()) {
logger.debug("Mapping [" + getExchangeDesc(exchange) + "] to " + r);
}
// 设置 GATEWAY_ROUTE_ATTR 为 匹配的 Route, 后续会一直用到这个Route实例!
exchange.getAttributes().put(GATEWAY_ROUTE_ATTR, r);
// 返回
return Mono.just(webHandler);
}).switchIfEmpty(Mono.empty().then(Mono.fromRunnable(() -> { // 匹配不到 Route
if (logger.isTraceEnabled()) {
logger.trace("No RouteDefinition found for [" + getExchangeDesc(exchange) + "]");
}
})));
}
protected Mono<Route> lookupRoute(ServerWebExchange exchange) {
return this.routeLocator.getRoutes()
.filter(route -> route.getPredicate().test(exchange))
.next()
.map(route -> {
if (logger.isDebugEnabled()) {
logger.debug("RouteDefinition matched: " + route.getId());
}
validateRoute(route, exchange);
return route;
});
}
SimpleHandlerAdapter
SimpleHandlerAdapter
是SpringWeb中的类, Springcloud Gateway中FilteringWebHandler
通过继承WebHandler
来对此处SpringWeb留下的这个扩展点进行扩充
public class SimpleHandlerAdapter implements HandlerAdapter {
@Override
public boolean supports(Object handler) {
return WebHandler.class.isAssignableFrom(handler.getClass());
}
@Override
public Mono<HandlerResult> handle(ServerWebExchange exchange, Object handler) {
WebHandler webHandler = (WebHandler) handler;
Mono<Void> mono = webHandler.handle(exchange);
return mono.then(Mono.empty());
}
}
由SimpleHandlerAdapter#handle
执行FilteringWebHandler
SimpleHandlerAdapter
实现了HandlerAdapter
接口, 来看下它的注释
/**
* Contract that decouples the {@link DispatcherHandler} from the details of
* invoking a handler and makes it possible to support any handler type.
*
* @author Rossen Stoyanchev
* @author Sebastien Deleuze
* @since 5.0
*/
public interface HandlerAdapter
意思是这个接口约定将DispatcherHandler
与调用处理程序的细节解耦,这使得它可以支持任何类型的handler
FilteringWebHandler
接着由FilteringWebHandler#handle
执行所有GatewayFilter
@Override
public Mono<Void> handle(ServerWebExchange exchange) {
// 获得 Route
Route route = exchange.getRequiredAttribute(GATEWAY_ROUTE_ATTR);
// 获得 GatewayFilter
List<GatewayFilter> gatewayFilters = route.getFilters();
List<GatewayFilter> combined = new ArrayList<>(this.globalFilters);
combined.addAll(gatewayFilters);
// 排序
//TODO: needed or cached?
AnnotationAwareOrderComparator.sort(combined);
logger.debug("Sorted gatewayFilterFactories: "+ combined);
// 创建 DefaultGatewayFilterChain
return new DefaultGatewayFilterChain(combined).filter(exchange);
}
FilteringWebHandler.DefaultGatewayFilterChain#filter
通过责任链模式将所有filters串成链条并执行
private static class DefaultGatewayFilterChain implements GatewayFilterChain {
private int index;
private final List<GatewayFilter> filters;
public DefaultGatewayFilterChain(List<GatewayFilter> filters) {
this.filters = filters;
}
@Override
public Mono<Void> filter(ServerWebExchange exchange) {
if (this.index < filters.size()) {
GatewayFilter filter = filters.get(this.index++);
return filter.filter(exchange, this);
} else {
return Mono.empty(); // complete
}
}
}
执行完这些过滤器,将请求转发到对应的代理服务器,至此,一次请求流程就结束了。注意,这里的过滤器由于是采用递归方式实现的责任链模式,不仅会在request进行处理,也会对response做一些处理。