Spring Cloud GateWay 源码解析实战 - FilteringWebHandler(更新ing)

简介: Spring Cloud GateWay 源码解析实战 - FilteringWebHandler(更新ing)
package org.springframework.cloud.gateway.handler;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import reactor.core.publisher.Mono;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.cloud.gateway.filter.OrderedGatewayFilter;
import org.springframework.cloud.gateway.filter.factory.GatewayFilterFactory;
import org.springframework.cloud.gateway.route.Route;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.AnnotationAwareOrderComparator;
import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.server.WebHandler;
import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.GATEWAY_ROUTE_ATTR;
/**
 * WebHandler that delegates to a chain of {@link GlobalFilter} instances and
 * {@link GatewayFilterFactory} instances then to the target {@link WebHandler}.
 *
 * @author Rossen Stoyanchev
 * @author Spencer Gibb
 * @since 0.1
 */
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);
  }
  private static List<GatewayFilter> loadFilters(List<GlobalFilter> 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());
  }
  /*
   * TODO: relocate @EventListener(RefreshRoutesEvent.class) void handleRefresh() {
   * this.combinedFiltersForRoute.clear();
   */
  @Override
  public Mono<Void> handle(ServerWebExchange exchange) {
    Route route = exchange.getRequiredAttribute(GATEWAY_ROUTE_ATTR);
    List<GatewayFilter> gatewayFilters = route.getFilters();
    List<GatewayFilter> combined = new ArrayList<>(this.globalFilters);
    combined.addAll(gatewayFilters);
    // TODO: needed or cached?
    AnnotationAwareOrderComparator.sort(combined);
    if (logger.isDebugEnabled()) {
      logger.debug("Sorted gatewayFilterFactories: " + combined);
    }
    return new DefaultGatewayFilterChain(combined).filter(exchange);
  }
  private static class DefaultGatewayFilterChain implements GatewayFilterChain {
    private final int index;
    private final List<GatewayFilter> filters;
    DefaultGatewayFilterChain(List<GatewayFilter> filters) {
      this.filters = filters;
      this.index = 0;
    }
    private DefaultGatewayFilterChain(DefaultGatewayFilterChain parent, int index) {
      this.filters = parent.getFilters();
      this.index = index;
    }
    public List<GatewayFilter> getFilters() {
      return filters;
    }
    @Override
    public Mono<Void> filter(ServerWebExchange exchange) {
      return Mono.defer(() -> {
        if (this.index < filters.size()) {
          GatewayFilter filter = filters.get(this.index);
          DefaultGatewayFilterChain chain = new DefaultGatewayFilterChain(this,
              this.index + 1);
          return filter.filter(exchange, chain);
        }
        else {
          return Mono.empty(); // complete
        }
      });
    }
  }
  private static class GatewayFilterAdapter implements GatewayFilter {
    private final GlobalFilter delegate;
    GatewayFilterAdapter(GlobalFilter delegate) {
      this.delegate = delegate;
    }
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
      return this.delegate.filter(exchange, chain);
    }
    @Override
    public String toString() {
      final StringBuilder sb = new StringBuilder("GatewayFilterAdapter{");
      sb.append("delegate=").append(delegate);
      sb.append('}');
      return sb.toString();
    }
  }
}
目录
相关文章
|
3天前
|
数据采集 消息中间件 监控
Flume数据采集系统设计与配置实战:面试经验与必备知识点解析
【4月更文挑战第9天】本文深入探讨Apache Flume的数据采集系统设计,涵盖Flume Agent、Source、Channel、Sink的核心概念及其配置实战。通过实例展示了文件日志收集、网络数据接收、命令行实时数据捕获等场景。此外,还讨论了Flume与同类工具的对比、实际项目挑战及解决方案,以及未来发展趋势。提供配置示例帮助理解Flume在数据集成、日志收集中的应用,为面试准备提供扎实的理论与实践支持。
20 1
|
13天前
|
监控 前端开发 JavaScript
实战篇:商品API接口在跨平台销售中的有效运用与案例解析
随着电子商务的蓬勃发展,企业为了扩大市场覆盖面,经常需要在多个在线平台上展示和销售产品。然而,手工管理多个平台的库存、价格、商品描述等信息既耗时又容易出错。商品API接口在这一背景下显得尤为重要,它能够帮助企业在不同的销售平台之间实现商品信息的高效同步和管理。本文将通过具体的淘宝API接口使用案例,展示如何在跨平台销售中有效利用商品API接口,以及如何通过代码实现数据的统一管理。
|
19天前
|
XML 存储 Java
Spring重要类解析
Spring重要类解析
19 0
|
17天前
|
安全 Java 数据安全/隐私保护
【深入浅出Spring原理及实战】「EL表达式开发系列」深入解析SpringEL表达式理论详解与实际应用
【深入浅出Spring原理及实战】「EL表达式开发系列」深入解析SpringEL表达式理论详解与实际应用
40 1
|
25天前
|
Java Nacos Sentinel
Spring Cloud Alibaba 面试题及答案整理,最新面试题
Spring Cloud Alibaba 面试题及答案整理,最新面试题
123 0
|
2天前
|
SQL API 数据库
Python中的SQLAlchemy框架:深度解析与实战应用
【4月更文挑战第13天】在Python的众多ORM(对象关系映射)框架中,SQLAlchemy以其功能强大、灵活性和易扩展性脱颖而出,成为许多开发者首选的数据库操作工具。本文将深入探讨SQLAlchemy的核心概念、功能特点以及实战应用,帮助读者更好地理解和使用这一框架。
|
3天前
|
XML Java 数据格式
Bean工厂探秘:解析Spring底层工厂体系BeanFactory的神奇之道
Bean工厂探秘:解析Spring底层工厂体系BeanFactory的神奇之道
13 0
Bean工厂探秘:解析Spring底层工厂体系BeanFactory的神奇之道
|
3天前
|
XML Java 数据格式
从入门到精通:Spring基础注解的全面解析
从入门到精通:Spring基础注解的全面解析
21 2
从入门到精通:Spring基础注解的全面解析
|
3天前
|
Java 数据库 Spring
切面编程的艺术:Spring动态代理解析与实战
切面编程的艺术:Spring动态代理解析与实战
18 0
切面编程的艺术:Spring动态代理解析与实战
|
3天前
|
Java 关系型数据库 MySQL
高级对象装配:解析Spring创建复杂对象的秘诀
高级对象装配:解析Spring创建复杂对象的秘诀
12 0
高级对象装配:解析Spring创建复杂对象的秘诀

推荐镜像

更多