Spring Cloud Gateway源码解析-05-请求处理之FilteringWebHandler

来源

SCG初始化解析之Route、Predicate、Filter的构建原理中我们提到了FilteringWebHandler会在GatewayAutoConfiguration中进行自动装配,并没有进一步阐述。

@Bean
public FilteringWebHandler filteringWebHandler(List<GlobalFilter> globalFilters) {
	return new FilteringWebHandler(globalFilters);
}
复制代码

可以看到在装配时会将所有的GlobalFilter组合进去。

public class FilteringWebHandler implements WebHandler {

	protected static final Log logger = LogFactory.getLog(FilteringWebHandler.class);

	private final List<GatewayFilter> globalFilters;

	public FilteringWebHandler(List<GlobalFilter> globalFilters) {
		this.globalFilters = loadFilters(globalFilters);
	}
	
    
	/**
	 * 此方法主要是将GlobalFilter适配为GatewayFilter
	 * @param filters
	 * @return
	 */
	private static List<GatewayFilter> loadFilters(List<GlobalFilter> filters) {
		return filters.stream().map(filter -> {
			//通过GatewayFilterAdapter将GlobalFilter适配为GatewayFilter
			GatewayFilterAdapter gatewayFilter = new GatewayFilterAdapter(filter);
			//判断GlobalFilter是否实现了Ordered接口
			if (filter instanceof Ordered) {
				int order = ((Ordered) filter).getOrder();
				//OrderedGatewayFilter是一个有序的网关过滤器实现类,在FilterChain,过滤器数组会首先按照order进行圣墟排序,按顺序过滤请求
				//返回OrderedGatewayFilter
				return new OrderedGatewayFilter(gatewayFilter, order);
			}
			return gatewayFilter;
		}).collect(Collectors.toList());
	}
}
复制代码


GlobalFilterGatewayFilter下边会进行讲解。

上节说到RoutePredicateHandlerMapping#getHandlerInternal方法会返回FilteringWebHandlerDispatcherHandler

class DispatcherHandler

@Override
public Mono<Void> handle(ServerWebExchange exchange) {
	if (this.handlerMappings == null) {
		return createNotFoundError();
	}
	return Flux.fromIterable(this.handlerMappings)
			.concatMap(mapping -> mapping.getHandler(exchange))
			.next()
        	//FilteringWebHandler
			.switchIfEmpty(createNotFoundError())
        	//执行handler逻辑
			.flatMap(handler -> invokeHandler(exchange, handler))
			.flatMap(result -> handleResult(exchange, result));
}

private Mono<HandlerResult> invokeHandler(ServerWebExchange exchange, Object handler) {
	if (this.handlerAdapters != null) {
		
		for (HandlerAdapter handlerAdapter : this.handlerAdapters) {
			//$1
			if (handlerAdapter.supports(handler)) {
				return handlerAdapter.handle(exchange, handler);
			}
		}
	}
	return Mono.error(new IllegalStateException("No HandlerAdapter: " + handler));
}
复制代码


$1处会遍历所有的HandlerAdapter判断是否支持该handler并执行handle逻辑。
在这里插入图片描述
此处会选择出SimpleHandlerAdapter

SimpleHandlerAdapter

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;
        //调用FilterWebHandler#handle
		Mono<Void> mono = webHandler.handle(exchange);
		return mono.then(Mono.empty());
	}

}
复制代码

可以看到SimpleHandlerAdaptersupperts方法只是判断了WebHandler是否为handler的子类。
在这里插入图片描述

FilteringWebHandler#handle

public class FilteringWebHandler implements WebHandler {
    
    private final List<GatewayFilter> globalFilters;
    
    @Override
	public Mono<Void> handle(ServerWebExchange exchange) {
        //获取到路由
		Route route = exchange.getRequiredAttribute(GATEWAY_ROUTE_ATTR);
        //获取到路由的Filter
		List<GatewayFilter> gatewayFilters = route.getFilters();
		
		List<GatewayFilter> combined = new ArrayList<>(this.globalFilters);
		//将GlobalFilter和路由的Filter合并
        combined.addAll(gatewayFilters);
		// TODO: needed or cached?
		//对Filter排序
		AnnotationAwareOrderComparator.sort(combined);

		if (logger.isDebugEnabled()) {
			logger.debug("Sorted gatewayFilterFactories: " + combined);
		}
		//创建FilterChain
		return new DefaultGatewayFilterChain(combined).filter(exchange);
	}
    
}
复制代码

GatewayFilterChain在SCG中只有一个实现DefaultGatewayFilterChainFilterChain很简单就不做过多介绍了。

上组传图
在这里插入图片描述

目前请求就到了上图我们红框的位置了,再经过GatewayFilterChain的前置过滤器过滤完发出代理请求,返回结果经过后置过滤器过滤后再返回。

引用官方文档的话

Clients make requests to Spring Cloud Gateway. If the Gateway Handler Mapping determines that a request matches a route, it is sent to the Gateway Web Handler. This handler runs the request through a filter chain that is specific to the request. The reason the filters are divided by the dotted line is that filters can run logic both before and after the proxy request is sent. All “pre” filter logic is executed. Then the proxy request is made. After the proxy request is made, the “post” filter logic is run.

简述Filter

  • GatewayFilter:引用官方文档的话,路由过滤器是来以某种方式修改传入的HTPP请求或者HTTP响应,作用于特定的路由,在SCG中通过FilterFactory来创建GatewayFilter
  • GlobalFilter:引用官方文档的话,GlobalFilter接口具有与GatewayFilter相同的签名,是特殊的过滤器,有条件的作用于所有的路由。

从两种Filter的装配时机与方式就可以看出来,两种Filter的作用域是不同的,GatewayFilter是在CachingRouteLocator装配时将我们配置的Filter信息对应的Filter绑定对应的路由上的,而GlobalFilter(所有的)是在装配FilteringWebHandler时组装进去的。

总结


解析到这里,SCG的请求从接入到处理流程我们就已经搞清楚了,但是不清楚具体的Filter的作用和哪些Filter是前置和后置,什么Filter用来发送代理请求,后边的文章我们会揭开它们真正的面纱。

猜你喜欢

转载自juejin.im/post/7032117405618798629