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

本文深入剖析Spring Cloud Gateway的路由匹配与过滤器工作原理,包括FilteringWebHandler的装配过程,GlobalFilter与GatewayFilter的区别及其如何作用于路由。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


系列文章

创作不易,如果对您有帮助,麻烦辛苦下小手点个关注,有任何问题都可以私信交流哈。
祝您虎年虎虎生威。


来源

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用来发送代理请求,后边的文章我们会揭开它们真正的面纱。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

壹氿

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值