文章标题:
Spring Cloud中Gateway服务入口的自定义过滤新方式
文章内容:

目录
过滤器执行顺序
在一个项目里,如果同时存在GatewayFilter和GlobalFilter,它们的执行顺序是怎样的呢?当请求完成路由后,网关会把项目中的GatewayFilter和GlobalFilter合并到一个过滤器链(集合)中,然后进行排序,依次执行这些过滤器。
每一个过滤器都得指定一个int类型的order值,默认是0,这代表该过滤的优先级。order值越小,优先级越高,执行顺序就越靠前。
- Filter能够通过实现Order接口或者添加@Order注解来指定order值。
- Spring Cloud Gateway提供的Filter由Spring来指定,用户自定义的Filter则由用户自己指定。
- 当过滤器的order值相同时,执行顺序会是defaultFilter > GatewayFilter > GlobalFilter。
自定义过滤器
Spring Cloud Gateway为过滤器提供了扩展功能,开发者能够依据实际业务来自定义过滤器,自定义过滤器同样支持GatewayFilter和GlobalFilter两种类型。
自定义GatewayFilter
自定义GatewayFilter时,需要去实现对应的GatewayFilterFactory接口,Spring Boot默认帮我们实现了抽象类AbstractGatewayFilterFactory,我们可以直接使用。
定义GatewayFilter
package gateway;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory;
import org.springframework.core.Ordered;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
@Slf4j
@Component
public class CustomGatewayFilterFactory extends AbstractGatewayFilterFactory<CustomConfig> implements Ordered {
public CustomGatewayFilterFactory() {
super(CustomConfig.class);
}
@Override
public GatewayFilter apply(CustomConfig config) {
return new GatewayFilter() {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
log.info("Pre Filter, config:{} ",config);
return chain.filter(exchange).then(Mono.fromRunnable(()->{
log.info("Post Filter....");
}));
}
};
}
@Override
public int getOrder() {
return Ordered.LOWEST_PRECEDENCE;
}
}
针对这个Filter的配置,使用CustomConfig来定义:
package gateway;
import lombok.Data;
@Data
public class CustomConfig {
private String name;
}
代码说明:
- 类名统一以GatewayFilterFactory结尾,默认情况下,过滤器的name会采用该定义类的前缀,这里的name是Custom(在yml配置中使用)。
- apply方法中同时包含Pre和Post过滤,then方法里是请求执行结束之后处理的逻辑。
- CustomConfig是一个配置类,该类只有一个属性name,和yml的配置相对应。
- 该类需要交给Spring管理,所以要加@Service注解。
- getOrder表示该过滤器的优先级,值越大,优先级越低。
配置过滤器
spring:
cloud:
gateway:
routes:
- id: order-service #路由规则id,随便起,不重复即可
uri: lb://order-service/ #目标服务地址
predicates: #路由条件
- Path=/order/**,/feign/**
filters:
- AddRequestParameter=userName, xiaoming
- name: Custom #过滤器名称
args:
name: test_custom
启动服务并访问
自定义GlobalFilter
GlobalFilter的实现比较简单,它不需要额外的配置,只需要实现GlobalFilter接口,就会自动过滤所有的请求。
定义GlobalFilter
package gateway;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
@Slf4j
@Component
public class CustomGlobalFilter implements GlobalFilter, Ordered {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
log.info("Pre Global Filter");
return chain.filter(exchange).then(Mono.fromRunnable(()->{
log.info("Post Global Filter...");
}));
}
@Override
public int getOrder() {
return Ordered.LOWEST_PRECEDENCE;
}
}
启动服务并访问
从日志中能够看出,当GatewayFilter和GlobalFilter过滤器的order一样时,会先执行GatewayFilter,然后再执行GlobalFilter。其中会先执行Pre GatewayFilter,接着执行Pre GlobalFilter,然后执行Post GlobalFilter,最后执行Post GatewayFilter。
服务部署
- 修改数据库、Nacos等相关配置。
- 对三个服务进行打包:product-service、order-service、gateway。
- 把jar上传到Linux服务器。
- 启动Nacos,启动前最好把data数据删除掉。
- 启动服务
#后台启动order-service,并设置输出日志到logs/order.log
nohup java -jar order-service.jar >logs/order.log &
#后台启动product-service,并设置输出日志到logs/order.log
nohup java -jar product-service.jar >logs/product-9090.log &
#启动网关
nohup java -jar gateway.jar >logs/gateway.log &
观察日志:
© 版权声明
文章版权归作者所有,未经允许请勿转载。
相关文章
没有相关内容!
暂无评论...