Springcloud Gateway 一次请求流程源码分析

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做一些处理。

流程图

在这里插入图片描述

  • 5
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值