忌才砟 发表于 2025-12-6 20:15:00

Spring Cloud Gateway 源码分析一

Spring Cloud Gateway 总体概述

请关注微信公众号:阿呆-bot
1. 项目概述

Spring Cloud Gateway 是 Spring 官方提供的 API 网关解决方案,基于 Spring Framework、Spring Boot 和 Project Reactor 构建。简单说,它就是微服务架构的"门卫",所有请求都要经过它,由它来决定请求应该转发到哪个服务。
为什么需要 Gateway?
想象一下,你的微服务架构有 10 个服务:

[*]用户服务(user-service)
[*]订单服务(order-service)
[*]商品服务(product-service)
[*]支付服务(payment-service)
[*]...等等
如果没有 Gateway,客户端需要知道每个服务的地址,而且每个服务都要单独处理认证、限流、监控等。有了 Gateway,客户端只需要知道 Gateway 的地址,Gateway 会负责:

[*]路由请求到正确的服务
[*]统一处理认证、授权
[*]统一处理限流、熔断
[*]统一处理监控、日志
1.1 核心特性

Gateway 提供了很多强大的功能,让我们一个个来看:

[*]✅ 动态路由: 支持配置文件和 API 动态配置路由
# 配置文件方式
spring:
cloud:
    gateway:
      routes:
      - id: user-service
          uri: http://localhost:8081// API 方式(动态添加路由)
routeDefinitionRepository.save(routeDefinition);
[*]✅ 请求匹配: 支持路径、方法、请求头、主机等多种匹配方式
predicates:
- Path=/api/users/**      # 路径匹配
- Method=GET            # 方法匹配
- Header=X-API-Key      # 请求头匹配
- Host=*.example.com      # 主机匹配
[*]✅ 过滤器链: 支持全局过滤器和路由过滤器
// 全局过滤器(应用于所有路由)
@Component
public class AuthFilter implements GlobalFilter { ... }

// 路由过滤器(只应用于特定路由)
filters:
- AddRequestHeader=X-User-Id, 123
[*]✅ 服务发现: 集成 Spring Cloud DiscoveryClient(Eureka、Consul 等)
# 自动从服务注册中心发现服务
spring:
cloud:
    gateway:
      discovery:
      locator:
          enabled: true
[*]✅ 负载均衡: 集成 Spring Cloud LoadBalancer
# 使用负载均衡
uri: lb://user-service# lb 表示负载均衡
[*]✅ 断路器: 集成 Spring Cloud Circuit Breaker
filters:
- name: CircuitBreaker
    args:
      name: user-service
      fallbackUri: forward:/fallback
[*]✅ 限流: 支持基于 Bucket4j 和 Redis 的限流
filters:
- name: RequestRateLimiter
    args:
      redis-rate-limiter.replenishRate: 10
      redis-rate-limiter.burstCapacity: 20
[*]✅ 多协议: 支持 HTTP/1.1、HTTP/2、WebSocket、gRPC
// WebSocket 支持
@Bean
public RouterFunction<ServerResponse> websocketRoute() {
    return RouterFunctions.route()
      .GET("/ws", websocketHandler)
      .build();
}
2. 主要目录结构

2.1 核心模块

spring-cloud-gateway/
├── spring-cloud-gateway-server-webflux/   # WebFlux 响应式实现
│   ├── config/                              # 自动配置类
│   ├── handler/                              # 请求处理器
│   ├── filter/                               # 过滤器实现
│   ├── route/                              # 路由相关
│   └── support/                              # 工具类

├── spring-cloud-gateway-server-webmvc/   # WebMVC 传统实现
│   ├── config/                              # 自动配置类
│   ├── handler/                              # 请求处理器
│   ├── filter/                               # 过滤器实现
│   ├── predicate/                            # 谓词实现
│   └── common/                               # 通用工具类

├── spring-cloud-gateway-proxyexchange-webflux/# WebFlux 代理交换
├── spring-cloud-gateway-proxyexchange-webmvc/   # WebMVC 代理交换

├── spring-cloud-gateway-dependencies/       # 依赖管理
├── spring-cloud-gateway-sample/            # 示例应用
└── spring-cloud-gateway-integration-tests/# 集成测试2.2 关键目录说明

spring-cloud-gateway-server-webflux

WebFlux 模式的核心实现:

[*]config/: 包含 GatewayAutoConfiguration 等自动配置类
[*]handler/: 包含 FilteringWebHandler、RoutePredicateHandlerMapping 等处理器
[*]filter/: 包含各种全局过滤器和过滤器工厂
[*]route/: 包含路由定义、路由定位器等
spring-cloud-gateway-server-webmvc

WebMVC 模式的核心实现:

[*]config/: 包含 GatewayServerMvcAutoConfiguration 等自动配置类
[*]handler/: 包含 ProxyExchangeHandlerFunction 等处理器
[*]filter/: 包含各种过滤器实现
[*]predicate/: 包含路由谓词实现
3. Gateway 关键用法和示例

3.1 基本配置

使用 WebFlux 模式

WebFlux 模式适合高并发场景,性能优秀。配置起来也很简单:
Maven 依赖:
<dependency>
    <groupId>org.springframework.cloud</groupId>
    spring-cloud-starter-gateway-server-webflux</artifactId>
</dependency>application.yml 配置:
spring:
cloud:
    gateway:
      server:
      webflux:
          enabled: true# 启用 Gateway WebFlux 模式
          routes:
            - id: user-service
            uri: lb://user-service# lb 表示负载均衡
            predicates:
                - Path=/api/users/**# 路径匹配
            filters:
                - StripPrefix=2# 去掉前两个路径段配置说明:

[*]id: 路由的唯一标识,可以随便起名字
[*]uri: 目标服务的地址,lb:// 表示使用负载均衡
[*]predicates: 路由匹配条件,这里匹配 /api/users/** 路径
[*]filters: 过滤器,StripPrefix=2 表示去掉 /api/users,只保留后面的路径
实际例子:
客户端请求:GET /api/users/123
匹配路由:user-service
应用过滤器:StripPrefix=2
转发到:http://user-service/123# 去掉了 /api/users使用 WebMVC 模式

WebMVC 模式适合传统 Spring MVC 应用,配置方式略有不同:
Maven 依赖:
<dependency>
    <groupId>org.springframework.cloud</groupId>
    spring-cloud-starter-gateway-server-webmvc</artifactId>
</dependency>application.yml 配置:
spring:
cloud:
    gateway:
      server:
      mvc:
          enabled: true# 启用 Gateway WebMVC 模式
          routes:
            - id: user-service
            uri: http://localhost:8081# 直接指定地址
            predicates:
                - path=/api/users/**# 注意:小写 path
            filters:
                - strip-prefix=2# 注意:小写 strip-prefix配置差异:

[*]WebFlux 使用 Path(大写),WebMVC 使用 path(小写)
[*]WebFlux 使用 StripPrefix,WebMVC 使用 strip-prefix
[*]WebMVC 不支持 lb:// 负载均衡,需要直接指定地址或使用服务发现
3.2 路由配置示例

路径重写

路径重写是 Gateway 的常用功能,可以修改请求路径再转发给下游服务。
配置示例:
spring:
cloud:
    gateway:
      routes:
      - id: rewrite-route
          uri: http://backend-service
          predicates:
            - Path=/api/**
          filters:
            - RewritePath=/api/(?<segment>.*), /$\{segment}实际例子:
客户端请求:GET /api/users/123
匹配路径:/api/**
应用重写规则:/api/(?<segment>.*) -> /${segment}
重写后路径:/users/123
转发到:http://backend-service/users/123正则表达式说明:

[*]/api/(?.*): 匹配 /api/ 后面的所有内容,捕获到 segment 组
[*]/${segment}: 使用捕获的 segment 组替换路径
[*]结果:/api/users/123 -> /users/123
更多例子:
# 去掉版本号
- RewritePath=/api/v1/(?<segment>.*), /api/$\{segment}
# /api/v1/users/123 -> /api/users/123

# 添加前缀
- RewritePath=/(?<segment>.*), /internal/$\{segment}
# /users/123 -> /internal/users/123请求头添加

添加请求头和响应头是 Gateway 的常见需求,可以传递上下文信息。
配置示例:
spring:
cloud:
    gateway:
      routes:
      - id: add-header-route
          uri: http://backend-service
          predicates:
            - Path=/api/**
          filters:
            - AddRequestHeader=X-Request-Id, ${random.uuid}
            - AddResponseHeader=X-Response-Time, ${T(java.lang.System).currentTimeMillis()}实际例子:
客户端请求:
GET /api/users/123
Headers: Authorization: Bearer token123

Gateway 转发给下游服务:
GET /api/users/123
Headers:
Authorization: Bearer token123# 保留原始头
X-Request-Id: 550e8400-e29b-41d4-a716-446655440000# 添加的新头

下游服务响应:
200 OK
Headers: Content-Type: application/json

Gateway 返回给客户端:
200 OK
Headers:
Content-Type: application/json# 保留原始头
X-Response-Time: 1699123456789# 添加的新头常用场景:

[*]请求追踪:添加 X-Request-Id,方便追踪请求链路
[*]用户信息:添加 X-User-Id,下游服务可以获取用户信息
[*]性能监控:添加 X-Response-Time,记录响应时间
[*]API 版本:添加 X-API-Version,支持 API 版本控制
限流配置

限流是保护下游服务的重要手段,防止被大量请求压垮。
配置示例:
spring:
cloud:
    gateway:
      routes:
      - id: rate-limit-route
          uri: http://backend-service
          predicates:
            - Path=/api/**
          filters:
            - name: RequestRateLimiter
            args:
                redis-rate-limiter.replenishRate: 10# 每秒补充 10 个令牌
                redis-rate-limiter.burstCapacity: 20# 突发容量 20 个令牌工作原理:
令牌桶算法:
- 每秒补充 10 个令牌(replenishRate)
- 桶容量 20 个令牌(burstCapacity)
- 每个请求消耗 1 个令牌

场景1:正常请求
- 每秒 10 个请求:正常通过 ✓
- 突发 20 个请求:前 20 个通过,后面的等待

场景2:超过限流
- 每秒 15 个请求:前 10 个通过,后 5 个被限流 ✗
- 返回 429 Too Many Requests实际例子:
// 限流配置
replenishRate: 10// 每秒 10 个请求
burstCapacity: 20// 突发最多 20 个请求

// 请求场景
第 1 秒:15 个请求
- 前 10 个:通过(使用补充的令牌)
- 后 5 个:通过(使用突发容量)

第 2 秒:25 个请求
- 前 10 个:通过(使用补充的令牌)
- 中间 10 个:通过(使用突发容量,桶里还有 10 个)
- 后 5 个:被限流(返回 429)

第 3 秒:5 个请求
- 全部通过(桶里补充了 10 个令牌)自定义限流键:
// 可以根据用户 ID 限流
@Bean
public KeyResolver userKeyResolver() {
    return exchange -> {
      String userId = exchange.getRequest().getHeaders().getFirst("X-User-Id");
      return Mono.just(userId != null ? userId : "anonymous");
    };
}3.3 编程式路由配置

WebFlux 模式

@Configuration
public class GatewayConfig {
   
    @Bean
    public RouteLocator customRouteLocator(RouteLocatorBuilder builder) {
      return builder.routes()
            .route("custom-route", r -> r
                .path("/api/custom/**")
                .uri("http://custom-service"))
            .build();
    }
}WebMVC 模式

@Configuration
public class GatewayMvcConfig {
   
    @Bean
    public RouterFunction<ServerResponse> customRouter() {
      return GatewayRouterFunctions.route("custom-route")
            .GET("/api/custom/**", HandlerFunctions.http())
            .build();
    }
}3.4 自定义过滤器

WebFlux 全局过滤器

@Component
public class CustomGlobalFilter implements GlobalFilter, Ordered {
   
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
      // 前置处理
      ServerHttpRequest request = exchange.getRequest();
      String requestId = UUID.randomUUID().toString();
      
      // 添加请求头
      ServerHttpRequest modifiedRequest = request.mutate()
            .header("X-Request-Id", requestId)
            .build();
      
      return chain.filter(exchange.mutate().request(modifiedRequest).build())
            .then(Mono.fromRunnable(() -> {
                // 后置处理
                log.info("Request processed: {}", requestId);
            }));
    }
   
    @Override
    public int getOrder() {
      return -1; // 高优先级
    }
}WebMVC 过滤器

@Component
public class CustomFilterFunction implements FilterFunction {
   
    @Override
    public ServerRequest filter(ServerRequest request) {
      // 处理请求
      return ServerRequest.from(request)
            .header("X-Request-Id", UUID.randomUUID().toString())
            .build();
    }
   
    @Override
    public ServerResponse filter(ServerRequest request, ServerResponse response) {
      // 处理响应
      return ServerResponse.from(response)
            .header("X-Response-Time", String.valueOf(System.currentTimeMillis()))
            .build();
    }
}4. 应用场景

4.1 微服务网关

这是 Gateway 最常见的应用场景。作为微服务架构的统一入口,Gateway 可以:
实际例子:
微服务架构:
- 用户服务(user-service:8081)
- 订单服务(order-service:8082)
- 商品服务(product-service:8083)
- 支付服务(payment-service:8084)

客户端只需要知道 Gateway 的地址(gateway:8080)

Gateway 配置:
spring:
cloud:
    gateway:
      routes:
      - id: user-service
          uri: http://user-service:8081
          predicates:
            - Path=/api/users/**
      - id: order-service
          uri: http://order-service:8082
          predicates:
            - Path=/api/orders/**统一处理横切关注点:

[*]认证、授权:在 Gateway 统一处理,下游服务不需要关心
@Component
public class AuthFilter implements GlobalFilter {
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
      String token = exchange.getRequest().getHeaders().getFirst("Authorization");
      if (!isValid(token)) {
            exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
            return exchange.getResponse().setComplete();
      }
      return chain.filter(exchange);
    }
}
[*]监控、日志:统一收集所有请求的指标和日志
@Component
public class LoggingFilter implements GlobalFilter {
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
      long startTime = System.currentTimeMillis();
      return chain.filter(exchange).then(Mono.fromRunnable(() -> {
            long duration = System.currentTimeMillis() - startTime;
            log.info("Request: {} {} - Duration: {}ms",
                exchange.getRequest().getMethod(),
                exchange.getRequest().getPath(),
                duration);
      }));
    }
}
[*]限流、熔断:保护下游服务,防止被压垮
filters:
- name: RequestRateLimiter
    args:
      redis-rate-limiter.replenishRate: 10
- name: CircuitBreaker
    args:
      name: user-service
      fallbackUri: forward:/fallback
4.2 API 聚合

Gateway 可以聚合多个后端服务的 API,减少客户端请求次数。
实际例子:
客户端需要获取用户订单详情,需要调用:
1. GET /api/users/123# 获取用户信息
2. GET /api/orders/456# 获取订单信息
3. GET /api/products/789# 获取商品信息

如果没有 Gateway,客户端需要发起 3 次请求。

有了 Gateway,可以创建一个聚合接口:
GET /api/user-order-detail?userId=123&orderId=456

Gateway 聚合逻辑:
@Component
public class AggregateFilter implements GlobalFilter {
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
      if (exchange.getRequest().getPath().value().equals("/api/user-order-detail")) {
            // 并行调用多个服务
            Mono<User> user = getUserService(exchange);
            Mono<Order> order = getOrderService(exchange);
            Mono<Product> product = getProductService(exchange);
            
            return Mono.zip(user, order, product)
                .map(tuple -> {
                  // 聚合结果
                  return new UserOrderDetail(tuple.getT1(), tuple.getT2(), tuple.getT3());
                })
                .flatMap(result -> {
                  // 返回聚合结果
                  return writeResponse(exchange, result);
                });
      }
      return chain.filter(exchange);
    }
}优势:

[*]减少客户端请求次数(3 次 -> 1 次)
[*]减少网络延迟
[*]提供统一的 API 接口
4.3 请求转换

Gateway 可以在转发请求时进行各种转换。
协议转换:
// HTTP 到 gRPC 转换
@Component
public class GrpcFilter implements GlobalFilter {
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
      if (exchange.getRequest().getPath().value().startsWith("/grpc/")) {
            // 将 HTTP 请求转换为 gRPC 请求
            return convertToGrpc(exchange)
                .flatMap(grpcRequest -> {
                  // 调用 gRPC 服务
                  return callGrpcService(grpcRequest);
                });
      }
      return chain.filter(exchange);
    }
}数据格式转换:
// JSON 到 XML 转换
@Component
public class FormatConverterFilter implements GlobalFilter {
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
      String accept = exchange.getRequest().getHeaders().getFirst("Accept");
      if ("application/xml".equals(accept)) {
            // 将 JSON 响应转换为 XML
            return chain.filter(exchange)
                .then(Mono.fromRunnable(() -> {
                  String json = getResponseBody(exchange);
                  String xml = convertJsonToXml(json);
                  setResponseBody(exchange, xml);
                }));
      }
      return chain.filter(exchange);
    }
}路径重写:
# 版本号处理
filters:
- RewritePath=/api/v1/(?<segment>.*), /api/$\{segment}
# /api/v1/users/123 -> /api/users/1234.4 安全控制

Gateway 可以作为安全的第一道防线。
API 认证和授权:
@Component
public class SecurityFilter implements GlobalFilter {
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
      String token = exchange.getRequest().getHeaders().getFirst("Authorization");
      
      // 验证 Token
      if (!isValidToken(token)) {
            exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
            return exchange.getResponse().setComplete();
      }
      
      // 检查权限
      if (!hasPermission(token, exchange.getRequest().getPath().value())) {
            exchange.getResponse().setStatusCode(HttpStatus.FORBIDDEN);
            return exchange.getResponse().setComplete();
      }
      
      return chain.filter(exchange);
    }
}IP 白名单/黑名单:
@Component
public class IpFilter implements GlobalFilter {
    private final Set<String> whitelist = Set.of("192.168.1.100", "10.0.0.1");
    private final Set<String> blacklist = Set.of("192.168.1.200");
   
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
      String clientIp = getClientIp(exchange);
      
      // 检查黑名单
      if (blacklist.contains(clientIp)) {
            exchange.getResponse().setStatusCode(HttpStatus.FORBIDDEN);
            return exchange.getResponse().setComplete();
      }
      
      // 检查白名单(如果配置了)
      if (!whitelist.isEmpty() && !whitelist.contains(clientIp)) {
            exchange.getResponse().setStatusCode(HttpStatus.FORBIDDEN);
            return exchange.getResponse().setComplete();
      }
      
      return chain.filter(exchange);
    }
}防止攻击:
// 防止 SQL 注入、XSS 攻击
@Component
public class SecurityFilter implements GlobalFilter {
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
      String query = exchange.getRequest().getURI().getQuery();
      
      // 检查 SQL 注入
      if (containsSqlInjection(query)) {
            exchange.getResponse().setStatusCode(HttpStatus.BAD_REQUEST);
            return exchange.getResponse().setComplete();
      }
      
      // 检查 XSS
      if (containsXss(query)) {
            exchange.getResponse().setStatusCode(HttpStatus.BAD_REQUEST);
            return exchange.getResponse().setComplete();
      }
      
      return chain.filter(exchange);
    }
}4.5 监控和可观测性

Gateway 可以统一收集监控数据,方便排查问题。
请求指标收集:
@Component
public class MetricsFilter implements GlobalFilter {
    private final MeterRegistry meterRegistry;
   
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
      long startTime = System.currentTimeMillis();
      String routeId = exchange.getAttribute(GATEWAY_ROUTE_ATTR).getId();
      
      return chain.filter(exchange).then(Mono.fromRunnable(() -> {
            long duration = System.currentTimeMillis() - startTime;
            
            // 记录指标
            meterRegistry.counter("gateway.requests", "route", routeId).increment();
            meterRegistry.timer("gateway.duration", "route", routeId).record(duration, TimeUnit.MILLISECONDS);
      }));
    }
}分布式追踪:
// 集成 Zipkin/Sleuth
@Component
public class TracingFilter implements GlobalFilter {
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
      // 创建追踪 Span
      Span span = tracer.nextSpan().name("gateway-request").start();
      
      try (Tracer.SpanInScope ws = tracer.withSpanInScope(span)) {
            // 添加追踪信息到请求头
            exchange.getRequest().mutate()
                .header("X-Trace-Id", span.context().traceId())
                .header("X-Span-Id", span.context().spanId())
                .build();
            
            return chain.filter(exchange)
                .doFinally(signalType -> span.end());
      }
    }
}性能监控:
// 监控响应时间、错误率等
@Component
public class PerformanceFilter implements GlobalFilter {
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
      long startTime = System.currentTimeMillis();
      
      return chain.filter(exchange)
            .doOnSuccess(v -> {
                long duration = System.currentTimeMillis() - startTime;
                // 记录成功请求的响应时间
                recordSuccess(duration);
            })
            .doOnError(throwable -> {
                // 记录错误
                recordError(throwable);
            });
    }
}5. 优缺点总结

5.1 优点 ✅


[*]功能丰富

[*]支持多种路由匹配方式
[*]丰富的过滤器生态
[*]集成 Spring Cloud 生态

[*]灵活配置

[*]支持配置文件配置
[*]支持编程式配置
[*]支持动态路由

[*]性能优秀(WebFlux 模式)

[*]非阻塞 I/O
[*]高并发支持
[*]资源利用率高

[*]易于集成

[*]与 Spring Boot 无缝集成
[*]支持服务发现
[*]支持负载均衡

[*]可扩展性强

[*]支持自定义过滤器
[*]支持自定义谓词
[*]插件化架构

6. 最佳实践

6.1 路由设计


[*]使用有意义的路由 ID
routes:
- id: user-service-route# 清晰的路由 ID
[*]合理使用路径匹配
predicates:
- Path=/api/v1/users/**# 使用版本化路径
[*]避免过于复杂的路由规则

[*]保持路由规则简单清晰
[*]避免深层嵌套的路径匹配

6.2 过滤器使用


[*]合理设置过滤器顺序
@Override
public int getOrder() {
    return Ordered.HIGHEST_PRECEDENCE;// 高优先级
}
[*]避免阻塞操作(WebFlux)
// ❌ 错误:阻塞操作
String result = blockingService.call();

// ✅ 正确:非阻塞操作
return Mono.fromCallable(() -> blockingService.call())
    .subscribeOn(Schedulers.boundedElastic());
[*]合理使用全局过滤器

[*]全局过滤器应用于所有路由
[*]路由过滤器只应用于特定路由

6.3 性能优化


[*]启用路由过滤器缓存(WebFlux)
spring:
cloud:
    gateway:
      server:
      webflux:
          route-filter-cache-enabled: true
[*]合理配置线程池(WebMVC)
server:
tomcat:
    threads:
      max: 200
      min-spare: 10
[*]使用连接池
spring:
cloud:
    gateway:
      httpclient:
      pool:
          max-connections: 500
6.4 监控和可观测性


[*]启用 Actuator
management:
endpoints:
    web:
      exposure:
      include: gateway,health,metrics
[*]集成分布式追踪
spring:
sleuth:
    zipkin:
      base-url: http://zipkin:9411
[*]监控关键指标

[*]请求数量
[*]响应时间
[*]错误率
[*]路由匹配率

7. 总结

Spring Cloud Gateway 是一个功能强大、灵活的 API 网关解决方案,提供了 WebMVC 和 WebFlux 两种实现模式,可以满足不同场景的需求。
选择建议:

[*]高并发场景: 选择 WebFlux 模式
[*]传统应用: 选择 WebMVC 模式
[*]微服务网关: 优先选择 WebFlux 模式
[*]快速开发: 选择 WebMVC 模式
关键要点:

[*]理解两种模式的差异和适用场景
[*]合理设计路由规则
[*]正确使用过滤器
[*]关注性能和监控
[*]遵循最佳实践

来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

溜椎干 发表于 7 天前

感谢分享,下载保存了,貌似很强大

泡市 发表于 3 天前

这个好,看起来很实用
页: [1]
查看完整版本: Spring Cloud Gateway 源码分析一