Skip to content

全局过滤器


Spring Cloud Gateway 中,全局过滤器Global Filters)是一种作用于所有路由的过滤器,它们可以对所有传入的请求和响应进行统一处理。与 局部过滤器(仅在特定路由上生效)不同,全局过滤器在 所有请求和响应 中都会生效,适合用于一些通用的、跨路由的处理逻辑。

全局过滤器是 Spring Cloud Gateway 处理请求链中的一个重要环节,可以执行一些常见的任务,比如:

  • **身份验证和授权:**在所有请求前验证用户的身份信息或权限,如 JWT 校验、OAuth 认证等。
  • **请求的统一日志记录:**记录请求信息、响应时间、状态码等,用于日志收集和分析。
  • **访问控制(如限制访问某些IP):**根据请求的 IP 地址、请求头等信息,做访问控制或限流。
  • **请求限流和重试:**如对请求进行计数,超过一定阈值时,限制请求速率。
  • **跨域处理(CORS):**为所有请求统一处理跨域资源共享(CORS)的请求头。
  • **响应头的统一处理:**为所有请求统一处响应头。

Spring Cloud Gateway 中,可以通过实现 GlobalFilter 接口来创建自定义全局过滤器。这个接口有两个方法:

  • filter(ServerWebExchange exchange, GatewayFilterChain chain):实际执行过滤操作的地方。
  • getOrder():指定过滤器的执行顺序,返回值越小,过滤器越早执行。
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.http.HttpStatus;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
@Component
public class MyGlobalFilter implements GlobalFilter, Ordered {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
// 在这里进行请求处理,例如身份验证或日志记录
String path = exchange.getRequest().getURI().getPath();
// 例如,如果请求路径包含 /admin ,则拒绝访问
if (path.contains("/admin")) {
exchange.getResponse().setStatusCode(HttpStatus.FORBIDDEN);
return exchange.getResponse().setComplete(); // 完成响应
}
// 如果通过过滤器,则继续执行链中的下一个过滤器
return chain.filter(exchange);
}
@Override
public int getOrder() {
// 返回一个整数,决定过滤器的执行顺序,数值越小越优先执行
return 1;
}
}

在上述例子中,定义了一个名为 MyGlobalFilter 的全局过滤器,用来拦截所有请求,并检查请求的路径。如果请求路径包含 /admin,则返回一个 403 Forbidden 状态码,拒绝访问。如果路径不包含 /admin,则继续传递请求。


自定义的全局过滤器需要在 Spring Boot 应用中注册。在 Spring Cloud Gateway 中,只需要在类上加上 @Component 注解,Spring 会自动将其注册为一个 Bean,无需额外配置。


  • 全局过滤器的执行顺序由 getOrder() 方法决定。getOrder() 返回的值越,过滤器越执行,返回值越,过滤器的执行顺序越
  • 如果需要多个全局过滤器,可以通过指定不同的 order 来控制它们的执行顺序。

4. 全局过滤器与局部过滤器的区别

Section titled “4. 全局过滤器与局部过滤器的区别”
特性全局过滤器局部过滤器
适用范围对所有路由生效只对指定的路由生效
定义方式通过实现 GlobalFilter 接口通过实现 GatewayFilter 接口
执行顺序根据 getOrder() 方法中的返回值控制顺序根据路由配置中的顺序控制
配置方式Spring 容器中作为 @Component 注册在路由配置文件中配置

全局过滤器的强大之处在于它们可以集中处理一些跨切关注点的逻辑,使得每个具体的路由更加简洁、关注点更加专注。


请求进入网关时会遇到三类过滤器:路由过滤器默认过滤器(DefaultFilter)和 全局过滤器(GlobalFilter。在请求路由之后,会将当前路由过滤器、默认过滤器和全局过滤器合并到一个过滤器链(集合)中,排序后依次执行每个过滤器。

  1. 所有过滤器都有一个 order 数字

这个数字决定执行顺序,数字越小 → 越先执行(优先级越高)。

  1. 全局过滤器(GlobalFilter
  • 自己指定 order
  • 两种方式:
    • 实现 Ordered 接口,重写 getOrder() 方法。
    • 在类上加 @Order 注解。
  1. 路由过滤器(Route Filter)和默认过滤器(DefaultFilter

order 值由 Spring 自动分配,默认是 按你写的顺序 从 1 开始递增。

  1. 如果多个过滤器的 order 值相同

执行优先级规则是:默认过滤器 > 路由过滤器 > 全局过滤器

  1. org.springframework.cloud.gateway.route.RouteDefinitionRouteLocator#getFilters() 方法首先加载 defaultFilters,然后加载某个 routefilters,最后进行合并。
  2. org.springframework.cloud.gateway.handler.FilteringWebHandler#handle()方法会加载全局过滤器,并与前面的过滤器合并后根据order排序,组织过滤器链。