来源
在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());
}
}
GlobalFilter
和GatewayFilter
下边会进行讲解。
上节说到RoutePredicateHandlerMapping
的#getHandlerInternal
方法会返回FilteringWebHandler
给DispatcherHandler
。
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());
}
}
可以看到SimpleHandlerAdapter
的supperts
方法只是判断了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中只有一个实现DefaultGatewayFilterChain
。FilterChain
很简单就不做过多介绍了。
上组传图
目前请求就到了上图我们红框的位置了,再经过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用来发送代理请求,后边的文章我们会揭开它们真正的面纱。