SpringCloud Gateway 中过滤器 GatewayFilterChain 介绍

2021-10-14 0 By admin

在Spring-Cloud-Gateway之请求处理流程中最终网关是将请求交给过滤器链表进行处理。核心接口:GatewayFilter,GlobalFilter,GatewayFilterChain。
查看整体类图

GatewayFilter 结构图
GatewayFilter 结构图

Spring Cloud Gateway 基于 Project Reactor 和 WebFlux,采用响应式编程风格,打开它的 Filter 的接口 GatewayFilter你会发现它只有一个方法 Filter。

一、GatewayFilterChain 网关过滤器链表

/**
 * 网关过滤链表接口
 * 用于过滤器的链式调用
 */
public interface GatewayFilterChain {
    /**
     *  链表启动调用入口方法*/
    Mono<Void> filter(ServerWebExchange exchange);
}

1.1、GatewayFilterChain 的默认实现类

/**
 * 网关过滤的链表,用于过滤器的链式调用
 * 过滤器链表接口的默认实现,包含2个构建函数:
 *  1.集合参数构建用于初始化构建链表
 *  2. index,parent参数用于构建当前执行过滤对应的下次执行的链表 
 */
private static class DefaultGatewayFilterChain implements GatewayFilterChain {
  //当前过滤执行过滤器在集合中索引
  private final int index;
  //过滤器集合
  private final List<GatewayFilter> filters;
  public DefaultGatewayFilterChain(List<GatewayFilter> filters) {
    this.filters = filters;
    this.index = 0;
  }
  /**
   * 构建
   * @param parent 上一个执行过滤器对应的FilterChain
   * @param index  当前要执行过滤器的索引
   */
  private DefaultGatewayFilterChain(DefaultGatewayFilterChain parent, int index) {
    this.filters = parent.getFilters();
    this.index = index;
  }

  public List<GatewayFilter> getFilters() {
    return filters;
  }

  /**
   * @param exchange the current server exchange
   * @return
   */
  @Override
  public Mono<Void> 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 执行顺序:

  1. 通过 GatewayFilter集合构建顶层的 GatewayFilterChain
  2. 调用顶层 GatewayFilterChain,获取第一个Filter,并创建下一个 Filter索引对应的 GatewayFilterChain
  3. 调用filter的filter方法执行当前filter,并将下次要执行的filter对应GatewayFilterChain传入。