今天我们来研究自定义Filter,自定义的Filter都是要实现GatewayFilter接口,如果需要指定排序则同时实现Order接口。filter有前置过滤器和后置过滤器,一般情况下,后置过滤器在then()方法里实现。下面实现一个自定义的filter,用来打印入参,以及统计请求到响应的耗时。
1.实现一个自定义过滤器
public class LogFilter implements GatewayFilter, Ordered {
private static final String START_TIME = "startTime";
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
// 下面3行代码在前过滤器pre filter执行
String url = exchange.getRequest().getURI().getRawPath();
System.out.println("请求地址:" + url + ",入参:" + exchange.getRequest().getQueryParams().toString());
exchange.getAttributes().put(START_TIME, System.currentTimeMillis());
// chain.filter里面的逻辑相当于后过滤器post filter,会在NettyRoutingFilter之后执行
return chain.filter(exchange).then(
Mono.fromRunnable(() -> {
Long startTime = exchange.getAttribute(START_TIME);
if(startTime != null){
System.out.println(url+ "耗时:" +
(System.currentTimeMillis() - startTime) + "ms");
}
})
);
}
@Override
public int getOrder() {
return 10;
}
}
2.分析前置和后置过滤器的执行顺序
验证上面代码的后置处理逻辑
我们知道全局过滤器NettyRoutingFilter就是请求目标服务器的filter,所有的http和https都会由这个过滤器做路由的转发,我们可以在这个类中打印个日志证下后置处理逻辑的执行时机。
发送请求:curl http://localhost:8080/get
日志输出:
请求地址:/get,入参:{}
Routing netty.....
/get耗时:1089ms
以上就可以说明then()里面的代码就是后置处理逻辑。
过滤器的执行会被组装成一个类似责任链的方式顺序执行,这对于前置过滤器是比较好理解的,但是要理解后置过滤器就要明白Reactor的Mono执行原理。一个请求进来,SCG会把global filter和gateway filter组成一个列表,其结构如下,前置过滤器处理顺序跟这个列表一致,filter1->filter4
但是后置过滤经过类似责任链的方式被组织成了下面这个结构,其执行顺序就反过来了:
下面我们通过例子来解释这个处理逻辑,首先要mono1.then(mono2)代表的是,mono1执行完之后mono2才会执行。
// 过滤器链
private static Mono filterChain = Mono.empty();
public static void main(String[] args) throws InterruptedException {
for (int i =1; i < 6;i++){
buildFilterChain(bulidFilter(i));
}
Flux.defer(() -> filterChain).subscribe();
Thread.sleep(1000);
}
// 构建过滤器链
private static Mono buildFilterChain(Mono mono){
return filterChain = mono.then(filterChain);
}
// 模拟创建filter
private static Mono bulidFilter(int order){
System.out.println("第" + order + "个过滤器的前置逻辑执行");
return Mono.fromRunnable(() -> System.out.println("第" + order + "个过滤器的后置逻辑执行"));
}
结果输出如下
第1个过滤器的前置逻辑执行
第2个过滤器的前置逻辑执行
第3个过滤器的前置逻辑执行
第4个过滤器的前置逻辑执行
第5个过滤器的前置逻辑执行
第5个过滤器的后置逻辑执行
第4个过滤器的后置逻辑执行
第3个过滤器的后置逻辑执行
第2个过滤器的后置逻辑执行
第1个过滤器的后置逻辑执行
3.小结
本篇文章从自定义一个过滤器出发,了解前置和后置过滤器的执行时机,然后分析了前置和后置过滤逻辑的实现原理,最后给出一个示例加深对这个原理的理解。