zuul如果两个filter的order一样,是如何排序的?(上)

简介: zuul如果两个filter的order一样,是如何排序的?

前言


最近有个网友问了一个问题,zuul中如果两个filter的order一样,是如何排序的?引起了我的兴趣,特地去阅读了它的源码。


正文


zuul是干什么的



如果你有使用过springcloud应该听说过zuul,它的定位是分布式微服务中的API网关服务,当然后面可能要被gateway替代了。zuul是一个L7应用程序网关,提供了动态路由,监视,弹性,安全性等功能。zuul的大部分功能是通过filter实现的。

57.png


zuul定义了四种不同生命周期的filter

56.png

为了方便操作,zuul内置了一些filter,这些filter主要通过@EnableZuulServer@EnableZuulProxy注解开启相关功能。@EnableZuulServer注解开启的filter功能如下:

55.png

@EnableZuulProxy注解除了开启上面这些filter功能之外,还开启了如下的功能:

51.png


如何自定义filter


只需继承ZuulFilter类,实现它的filterTypefilterOrdershouldFilterrun方法即可,具体实现可参考如下代码:

public class LogFilter extends ZuulFilter {
    @Override
    public String filterType() {
        return FilterConstants.PRE_TYPE;
    }
    @Override
    public int filterOrder() {
        return 1;
    }
    @Override
    public boolean shouldFilter() {
        return RequestContext.getCurrentContext().sendZuulResponse();
    }
    @Override
    public Object run() throws ZuulException {
        RequestContext currentContext = RequestContext.getCurrentContext();
        HttpServletRequest request = currentContext.getRequest();
        log.info("zuul pre filter-->" + request.getRequestURL() + "-->" + request.getMethod());
        return null;
    }
}


上面的四个方法有哪些作用呢?


方法名称 作用
filterType filter类型,包含:pre、routing、post和error四种类型
filterOrder 排序,该值越小,filter越早执行
shouldFilter 开关,表示是否需要执行该filter
run filter具体的功能方法

需要注意的是,要想使zuul的功能生效,切记要在springboot启动类上定义@EnableZuulServer@EnableZuulProxy注解,表示开启zuul的功能。


filterOrder是如何排序的


先看看所有的zuulFilter在哪里执行的,谜底就在FilterProcessor类的runFilters方法中。

微信图片_20220518110819.png

该方法很简单,先获取所有zuulFilter,然后遍历所有zuulFilter,调用processZuulFilter方法执行具体的zuulFilter,然后将执行结果返回。

我们重点看看这个方法


FilterLoader.getInstance().getFiltersByType(sType);

该方法的具体逻辑

53.png

  1. 根据filterType从缓存中获取filter集合,如果缓存中有直接返回
  2. 如果缓存中没有,则创建filter集合,将所有filter中跟filterType的filter添加到filter集合中。
  3. 排序filter集合
  4. 将新创建的filter集合放入缓存。

从上面可以看出filter的排序是通过如下方法执行的:


Collections.sort(list);


该方法底层其实是通过listsort方法实现的

52.png

看看ArrayListsort方法,传入的Comparator为null

51.png

它的底层又是通过Arrays类的静态方法sort实现的

50.png

由于上一步Comparator为null,则会执行sort方法。

49.png

该方法是通过ComparableTimSort类的sort方法实现的,这个方法是最核心的方法了

48.png

我们可以看到该方法其实是通过binarySort二分查找排序的。

47.png

通过compareTo方法比较大小。

我们回头再看看ZuulFilter

46.png

它实现了Comparable接口,重写了compareTo方法

45.png

所以,看到这里我们可以得出结论:ZuulFilter是通过Integercompare方法比较filterOrder参数值大小来排序的。



相关文章
|
10月前
Stream方法使用-filter、sorted、distinct、limit
Stream方法使用-filter、sorted、distinct、limit
61 0
|
11月前
filter和find的区别
filter和find的区别
|
2月前
|
JavaScript 前端开发
filter() 方法使用
filter() 方法使用
22 0
|
11月前
es6 filter方法的使用
es6 filter方法的使用
77 0
|
SQL 关系型数据库 MySQL
GROUP BY和ORDER BY的区别
GROUP BY和ORDER BY的区别
248 0
|
Java 数据管理 Spring
【Spring-data-jpa】利用@query组合查询
【Spring-data-jpa】利用@query组合查询
164 0
|
Java 开发者
使用filter-mapping控制多个Filter的执行顺序| 学习笔记
快速学习使用filter-mapping控制多个Filter的执行顺序。
207 0
使用filter-mapping控制多个Filter的执行顺序| 学习笔记
|
Java Spring
zuul如果两个filter的order一样,是如何排序的?(下)
zuul如果两个filter的order一样,是如何排序的?(下)
zuul如果两个filter的order一样,是如何排序的?(下)
|
Java Spring
spring data jpa中@Query中的模糊查询<like关键字>
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/tomnic_ylwang/article/details/47340799 ...
2409 0
ES6—17:筛选数组(filter)
ES6—17:筛选数组(filter)
126 0
ES6—17:筛选数组(filter)