在开发网关的时候,我们可以为我们的所有路由器定义同样的filter,这样就不用为每个route单独进行配置,有几种实现方式:
一:通过配置继承了AbstractGatewayFilterFactory的bean来进行
在配置文件中增加default-filters
spring:
application:
name: gateway
profiles:
active: prod
cloud:
gateway:
default-filters:
- name: ModifyRequestBody
- name: MyLog
routes:
- id: route1
uri: lb://route1
predicates:
- Path=/route1/**
- id: route2
uri: lb://route2
predicates:
- Path=/route2/**
ModifyRequestBody 和 MyLog 是过滤器的名字,他们都继承了AbstractGatewayFilterFactory,这样gateway在启动的时候,就会把配置的名字加上GatewayFilterFactory的后缀作为bean的名字进行加载,在这个例子中就是 ModifyRequestBodyGatewayFilterFactory 和 MyLogGatewayFilterFactory 这个两个bean,其中ModifyRequestBodyGatewayFilterFactory是gateway自带的类,MyLogGatewayFilterFactory是我自己实现的类,大家可以通过这样的方式自定义自己的过滤器。
但这种方式有一个问题,要注意一下,众所周知,路由器除了配置文件,还可以通过java 代码的方式进行配置,如下:
@Bean
public RouteLocator routeLocator(RouteLocatorBuilder builder) {
return builder.routes()
.route(r -> r.path("/test/**")
.uri("lb://test")
.order(0)
.id("test")
)
.build();
}
或者我们也可以自己进行动态路由的配置,网上有很多例子,我就不贴出来了
而上边那种通过yml或properties文件配置默认过滤器的方式,对 java代码配置的路由器不生效
只对配置文件和动态配置的路由生效(这个坑我进行了一上午的尝试对比才发现)
因为通过使用代码定义路由使用的是 RouteLocator 这个类
而通过配置文件或者外部存储器配置路由使用的是 RouteDefinitionLocator 的实现类进行的,有 4个实现类:
- PropertiesRouteDefinitionLocator ,从配置文件( 例如,YML / Properties 等 ) 读取
- RouteDefinitionRepository ,从存储器( 例如,内存 / Redis / MySQL 等 )读取(默认使用的是从内存)
- DiscoveryClientRouteDefinitionLocator ,从注册中心( 例如,Eureka / Zookeeper 等 )读取
- CompositeRouteDefinitionLocator ,组合多种 RouteDefinitionLocator 的实现
这里应该是,配置gateway自带的过滤器还是生效的,但是自己继承了AbstractGatewayFilterFactory的类就不生效,因为之前的项目配置过自带的Hystrix过滤器生效了
如果想让自己的过滤器对所有的路由生效,就用到这第二种方式
二:通过实现GlobalFilter的方式进行,
这样的过滤器对所有的路由都生效,而想要gateway中已有的过滤器功能,可以把其中的代码逻辑扣出来放进自己的类中。可以参照这篇 《spring cloud gateway 二次开发之 处理 requestBody》 https://www.jianshu.com/p/a5fc8039d236