Spring-Cloud-Gateway 源码解析 —— 过滤器 (4.1) 之 GatewayFilter 一览

扫码关注公众号:Java 技术驿站

发送:vip
获取永久解锁本站全部文章的链接

撸了今年阿里、腾讯和美团的面试,我有一个重要发现…….

摘要: 原创出处 http://www.iocoder.cn/Spring-Cloud-Gateway/filter-intro/ 「芋道源码」欢迎转载,保留摘要,谢谢!

本文主要基于 Spring-Cloud-Gateway 2.0.X M4


1. 概述

本文主要对 过滤器 GatewayFilter 做整体的认识

过滤器整体类图如下 :

是不是有点疑惑 GlobalFilter 与 GatewayFilter 的关系 ?且见本文分晓。


推荐 Spring Cloud 书籍

推荐 Spring Cloud 视频

2. GatewyFilter

org.springframework.cloud.gateway.filter.GatewayFilter ,网关过滤器接口,代码如下 :

public interface GatewayFilter {

    /**
     * Process the Web request and (optionally) delegate to the next
     * {@code WebFilter} through the given {@link GatewayFilterChain}.
     * @param exchange the current server exchange
     * @param chain provides a way to delegate to the next filter
     * @return {@code Mono<Void>} to indicate when request processing is complete
     */
    Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain);

}

GatewayFilter 有三种类型的子类实现,我们下面每节介绍一种。

2.1 GatewayFilterFactory 内部类

在每个 GatewayFilterFactory 实现类的 #apply(Tuple) 方法里,都声明了一个实现 GatewayFilter 的内部类,以 AddRequestHeaderGatewayFilterFactory 的代码举例子 :

  1: public class AddRequestHeaderGatewayFilterFactory implements GatewayFilterFactory {
  2:
  3:    @Override
  4:    public List<String> argNames() {
  5:        return Arrays.asList(NAME_KEY, VALUE_KEY);
  6:    }
  7:
  8:    @Override
  9:    public GatewayFilter apply(Tuple args) {
 10:        String name = args.getString(NAME_KEY);
 11:        String value = args.getString(VALUE_KEY);
 12:
 13:        return (exchange, chain) -> { // GatewayFilter  
 14:            ServerHttpRequest request = exchange.getRequest().mutate()
 15:                    .header(name, value)
 16:                    .build();
 17:
 18:            return chain.filter(exchange.mutate().request(request).build());
 19:        };
 20:    }
 21: }
  • 第 13 至 19 行 :定义了一个 GatewayFilter 内部实现类

《Spring-Cloud-Gateway 源码解析 —— 过滤器 (4.2) 之 GatewayFilterFactory 过滤器工厂》 ,我们会详细解析每个 GatewayFilterFactory 定义的GatewayFilter 内部实现类

2.2 OrderedGatewayFilter

org.springframework.cloud.gateway.filter.OrderedGatewayFilter有序的网关过滤器实现类。在 FilterChain 里,过滤器数组首先会按照 order 升序排序,按照顺序过滤请求。代码如下 :

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<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        return this.delegate.filter(exchange, chain);
    }

    @Override
    public int getOrder() {
        return this.order;
    }
}
  • delegate 属性,委托的 GatewayFilter 。
  • order 属性,顺序。
  • #filter(ServerWebExchange, GatewayFilterChain) 方法,使用 delegate 过滤请求。

2.3 GatewayFilterAdapter

org.springframework.cloud.gateway.handler.FilteringWebHandler.GatewayFilterAdapter ,网关过滤器适配器。在 GatewayFilterChain 使用 GatewayFilter 过滤请求,所以通过 GatewayFilterAdapter 将 GlobalFilter 适配成 GatewayFilter 。GatewayFilterAdapter 代码如下 :

private static class GatewayFilterAdapter implements GatewayFilter {

    private final GlobalFilter delegate;

    public GatewayFilterAdapter(GlobalFilter delegate) {
        this.delegate = delegate;
    }

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        return this.delegate.filter(exchange, chain);
    }
}
  • delegate 属性,委托的 GlobalFilter 。
  • #filter(ServerWebExchange, GatewayFilterChain) 方法,使用 delegate 过滤请求。

在 FilteringWebHandler 初始化时,将 GlobalFilter 委托成 GatewayFilterAdapter ,代码如下 :

  1: public class FilteringWebHandler implements WebHandler {
  2:
  3:     /**
  4:      * 全局过滤器
  5:      */
  6:    private final List<GatewayFilter> globalFilters;
  7:
  8:    public FilteringWebHandler(List<GlobalFilter> globalFilters) {
  9:        this.globalFilters = loadFilters(globalFilters);
 10:    }
 11:
 12:    private static List<GatewayFilter> loadFilters(List<GlobalFilter> filters) {
 13:        return filters.stream()
 14:                .map(filter -> {
 15:                    GatewayFilterAdapter gatewayFilter = new GatewayFilterAdapter(filter);
 16:                    if (filter instanceof Ordered) {
 17:                        int order = ((Ordered) filter).getOrder();
 18:                        return new OrderedGatewayFilter(gatewayFilter, order);
 19:                    }
 20:                    return gatewayFilter;
 21:                }).collect(Collectors.toList());
 22:    }
 23: }
  • 第 16 至 19 行 :当 GlobalFilter 子类实现了 org.springframework.core.Ordered 接口,在委托一层 OrderedGatewayFilter 。这样 AnnotationAwareOrderComparator#sort(List) 方法好排序。
  • 第 20 行 :当 GlobalFilter 子类没有实现了 org.springframework.core.Ordered 接口,在 AnnotationAwareOrderComparator#sort(List) 排序时,顺序值为 Integer.MAX_VALUE
  • 目前 GlobalFilter 都实现了 org.springframework.core.Ordered 接口。

3. GlobalFilter

org.springframework.cloud.gateway.filter.GlobalFilter ,全局过滤器接口,代码如下 :

public interface GlobalFilter {

    /**
     * Process the Web request and (optionally) delegate to the next
     * {@code WebFilter} through the given {@link GatewayFilterChain}.
     * @param exchange the current server exchange
     * @param chain provides a way to delegate to the next filter
     * @return {@code Mono<Void>} to indicate when request processing is complete
     */
    Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain);

}
  • GlobalFilter 和 GatewayFilter 的 #filter(ServerWebExchange, GatewayFilterChain) 方法签名一致。官方说,未来的版本将作出一些调整。

    FROM 《Spring Cloud Gateway》
    This interface and usage are subject to change in future milestones

  • GlobalFilter 会作用到所有的 Route 上。

GlobalFilter 实现类如下类图 :

  • RoutingFilter

    • NettyRoutingFilter
    • WebClientHttpRoutingFilter
    • WebsocketRoutingFilter
    • ForwardRoutingFilter
  • 成对的 Filter

    • NettyRoutingFilter / NettyRoutingFilter
    • WebClientHttpRoutingFilter / WebClientWriteResponseFilter

梳理 GlobalFilter 的顺序如下 :

GlobalFilter 顺序 文章
NettyWriteResponseFilter -1 《Spring-Cloud-Gateway 源码解析 —— 过滤器 (4.7) 之 NettyRoutingFilter》
WebClientWriteResponseFilter -1 《Spring-Cloud-Gateway 源码解析 —— 过滤器 (4.8) 之 WebClientHttpRoutingFilter》
RouteToRequestUrlFilter 10000 《Spring-Cloud-Gateway 源码解析 —— 过滤器 (4.3) 之 RouteToRequestUrlFilter》
LoadBalancerClientFilter 10100 《Spring-Cloud-Gateway 源码解析 —— 过滤器 (4.4) 之 LoadBalancerClientFilter 负载均衡》
ForwardRoutingFilter Integer.MAX_VALUE 《Spring-Cloud-Gateway 源码解析 —— 过滤器 (4.5) 之 ForwardRoutingFilter》
NettyRoutingFilter Integer.MAX_VALUE 《Spring-Cloud-Gateway 源码解析 —— 过滤器 (4.7) 之 NettyRoutingFilter》
WebClientHttpRoutingFilter Integer.MAX_VALUE 《Spring-Cloud-Gateway 源码解析 —— 过滤器 (4.8) 之 WebClientHttpRoutingFilter》
WebsocketRoutingFilter Integer.MAX_VALUE 《Spring-Cloud-Gateway 源码解析 —— 过滤器 (4.6) 之 WebSocketRoutingFilter》

TODO 【3030】

4. GatewayFilterChain

org.springframework.cloud.gateway.filter.GatewayFilterChain ,网关过滤器链接口。代码如下 :

public interface GatewayFilterChain {

    /**
     * Delegate to the next {@code WebFilter} in the chain.
     * @param exchange the current server exchange
     * @return {@code Mono<Void>} to indicate when request handling is complete
     */
    Mono<Void> filter(ServerWebExchange exchange);

}

org.springframework.cloud.gateway.handler.FilteringWebHandler.GatewayFilterAdapter ,网关过滤器链默认实现类。代码如下 :

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
        }
    }
}
赞(1) 打赏

如未加特殊说明,此网站文章均为原创,转载必须注明出处。Java 技术驿站 » Spring-Cloud-Gateway 源码解析 —— 过滤器 (4.1) 之 GatewayFilter 一览
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

关注【Java 技术驿站】公众号,每天早上 8:10 为你推送一篇技术文章


扫描二维码关注公众号

加 chenssy 为好友,交流技术


关注【Java 技术驿站】公众号 回复 “VIP”,获取 VIP 地址永久关闭弹出窗口

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏