天天看点

gateway中的局部过滤器_详解SpringCloud Gateway之过滤器GatewayFilter

在Spring-Cloud-Gateway之请求处理流程文中我们了解最终网关是将请求交给过滤器链表进行处理,接下来我们阅读Spring-Cloud-Gateway的整个过滤器类结构以及主要功能

通过源码可以看到Spring-Cloud-Gateway的filter包中吉接口有如下三个,GatewayFilter,GlobalFilter,GatewayFilterChain,下来我依次阅读接口的主要实现功能。

GatewayFilterChain

类图

gateway中的局部过滤器_详解SpringCloud Gateway之过滤器GatewayFilter

代码

public interface GatewayFilterChain {

Mono filter(ServerWebExchange exchange);

}

private static class DefaultGatewayFilterChain implements GatewayFilterChain {

private final int index;

private final List filters;

public DefaultGatewayFilterChain(List filters) {

this.filters = filters;

this.index = 0;

}

private DefaultGatewayFilterChain(DefaultGatewayFilterChain parent, int index) {

this.filters = parent.getFilters();

this.index = index;

}

public List getFilters() {

return filters;

}

@Override

public Mono filter(ServerWebExchange exchange) {

return Mono.defer(() -> {

if (this.index < filters.size()) {

//获取当前索引的过滤器

GatewayFilter filter = filters.get(this.index);

//构建当前索引的下一个过滤器的FilterChain

DefaultGatewayFilterChain chain = new DefaultGatewayFilterChain(this, this.index + 1);

//调用过滤器的filter方法执行过滤器

return filter.filter(exchange, chain);

} else {

//当前索引大于等于过滤集合大小,标识所有链表都已执行完毕,返回空

return Mono.empty(); // complete

}

});

}

}

过滤器的GatewayFilterChain 执行顺序

通过GatewayFilter集合构建顶层的GatewayFilterChain

调用顶层GatewayFilterChain,获取第一个Filter,并创建下一个Filter索引对应的GatewayFilterChain

调用filter的filter方法执行当前filter,并将下次要执行的filter对应GatewayFilterChain传入。

GatewayFilter

类图

gateway中的局部过滤器_详解SpringCloud Gateway之过滤器GatewayFilter

public interface GatewayFilter extends ShortcutConfigurable {

String NAME_KEY = "name";

String VALUE_KEY = "value";

Mono filter(ServerWebExchange exchange, GatewayFilterChain chain);

}

网关过滤器接口,有且只有一个方法filter,执行当前过滤器,并在此方法中决定过滤器链表是否继续往下执行,接下来我们看下几个主要的功能实现类

OrderedGatewayFilter

public class OrderedGatewayFilter implements GatewayFilter, Ordered {

//目标过滤器

private final GatewayFilter delegate;

//排序字段

private final int order;

public OrderedGatewayFilter(GatewayFilter delegate, int order) {

this.delegate = delegate;

this.order = order;

}

@Override

public Mono filter(ServerWebExchange exchange, GatewayFilterChain chain) {

return this.delegate.filter(exchange, chain);

}

}

OrderedGatewayFilter实现类主要目的是为了将目标过滤器包装成可排序的对象类型。是目标过滤器的包装类

GatewayFilterAdapter

private static class GatewayFilterAdapter implements GatewayFilter {

private final GlobalFilter delegate;

public GatewayFilterAdapter(GlobalFilter delegate) {

this.delegate = delegate;

}

@Override

public Mono filter(ServerWebExchange exchange, GatewayFilterChain chain) {

return this.delegate.filter(exchange, chain);

}

}

GatewayFilterAdapter实现类主要目的是为了将GlobalFilter过滤器包装成GatewayFilter类型的对应。是GlobalFilter过滤器的包装类

GlobalFilter

gateway中的局部过滤器_详解SpringCloud Gateway之过滤器GatewayFilter

GlobalFilter 为请求业务以及路由的URI转换为真实业务服务的请求地址的核心过滤器,不需要配置,模式系统初始化时加载,并作用在每个路由上。

初始化加载,通过GatewayAutoConfiguration自动创建

GatewayAutoConfiguration 类

@Bean

public NettyRoutingFilter routingFilter(HttpClient httpClient,

ObjectProvider> headersFilters) {

return new NettyRoutingFilter(httpClient, headersFilters);

}

@Bean

public NettyWriteResponseFilter nettyWriteResponseFilter(GatewayProperties properties) {

return new NettyWriteResponseFilter(properties.getStreamingMediaTypes());

}

GatewayLoadBalancerClientAutoConfiguration 类

@Bean

@ConditionalOnBean(LoadBalancerClient.class)

public LoadBalancerClientFilter loadBalancerClientFilter(LoadBalancerClient client) {

return new LoadBalancerClientFilter(client);

}

GlobalFilter转换成GatewayFilter,并作用于每个路由上,在FilteringWebHandler实现

FilteringWebHandler类

private static List loadFilters(List filters) {

return filters.stream()

.map(filter -> {

//将所有的全局过滤器包装成网关过滤器

GatewayFilterAdapter gatewayFilter = new GatewayFilterAdapter(filter);

//判断全局过滤器是否实现了可排序接口

if (filter instanceof Ordered) {

int order = ((Ordered) filter).getOrder();

//包装成可排序的网关过滤器

return new OrderedGatewayFilter(gatewayFilter, order);

}

return gatewayFilter;

}).collect(Collectors.toList());

}

@Override

public Mono handle(ServerWebExchange exchange) {

//获取请求上下文设置的路由实例

Route route = exchange.getRequiredAttribute(GATEWAY_ROUTE_ATTR);

//获取路由定义下的网关过滤器集合

List gatewayFilters = route.getFilters();

//组合全局的过滤器与路由配置的过滤器

List combined = new ArrayList<>(this.globalFilters);

//添加路由配置过滤器到集合尾部

combined.addAll(gatewayFilters);

//对过滤器进行排序

//TODO: needed or cached?

AnnotationAwareOrderComparator.sort(combined);

logger.debug("Sorted gatewayFilterFactories: "+ combined);

//创建过滤器链表对其进行链式调用

return new DefaultGatewayFilterChain(combined).filter(exchange);

}

loadFilters方法是将全局路由使用GatewayFilterAdapter包装成GatewayFilter

handle方法

获取当前请求使用的路由Route

获取路由配置的过滤器集合route.getFilters()

合并全过滤器与路由配置过滤器combined

对过滤器排序AnnotationAwareOrderComparator.sort

通过过滤器集合构建顶级链表DefaultGatewayFilterChain,并对其当前请求调用链表的filter方法。

==备注==:

Spring-Cloud-Gateway的过滤器接口分为两种:

GlobalFilter : 全局过滤器,不需要在配置文件中配置,作用在所有的路由上,最终通过GatewayFilterAdapter包装成GatewayFilterChain可识别的过滤器

GatewayFilter : 需要通过spring.cloud.routes.filters 配置在具体路由下,只作用在当前路由上或通过spring.cloud.default-filters配置在全局,作用在所有路由上

至此,网关过滤器的整个结构以及加载使用流程源码已经阅读完毕,下篇重点学习下路由配置的过滤器加载创建流程

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。