国贸行业的网站建设,有赞云 wordpress,网站模板 站长之家,企业网站可以自己做过滤器的种类
Spring-Cloud-Gateway中提供了3种类型的过滤器#xff0c;分别是#xff1a;路由过滤器、Default过滤器和Global过滤器。
路由过滤器和Default过滤器
路由过滤器和Default过滤器本质上是同一种过滤器#xff0c;只不过作用范围不一样#xff0c;路由过滤器…过滤器的种类
Spring-Cloud-Gateway中提供了3种类型的过滤器分别是路由过滤器、Default过滤器和Global过滤器。
路由过滤器和Default过滤器
路由过滤器和Default过滤器本质上是同一种过滤器只不过作用范围不一样路由过滤器只针对单个路由起作用而Default过滤器对整个路由表中所有的路由都起作用这2个过滤器的处理逻辑都是Spring已经内置好的无须开发人员来写代码只需要做一下配置即可。
Spring已经提供好了30多种这样的过滤器比如
AddRequestHeaderAddRequestParameterStripPrefix… 这些过滤器都是org.springframework.cloud.gateway.filter.GatewayFilter的子类每一种过滤器都是由一种过滤器工厂来生成的比如AddRequestHeaderGatewayFilterFactory生成AddRequestHeader的过滤器AddRequestParameterGatewayFilterFactory生成AddRequestParameter的过滤器StripPrefixGatewayFilterFactory生成StripPrefix的过滤器
Global过滤器
Global过滤器与上面两个不一样Global过滤器需要开发人员自己来实现业务逻辑并且它是org.springframework.cloud.gateway.filter.GlobalFilter的子类。
过滤器的执行顺序
如果是Global过滤器可以让Global过滤器实现org.springframework.core.Ordered接口来设置过滤器的顺序但是这里注意org.springframework.core.annotation.Order这个注解是不起作用的。
如果是路由过滤器和Default过滤器他们的处理逻辑是Spring内置的因此他们的顺序是按照声明的顺序从1开始递增的比如 routes:- id: userserviceuri: lb://userservicepredicates:- Path/user/**filters:- AddRequestHeaderRouterFilter1, router1- AddRequestHeaderRouterFilter2, router2default-filters:- AddRequestHeaderDefaultFilter1, default1- AddRequestHeaderDefaultFilter1, default2以上的配置种router1的order是1router2的order是2default1的order是1default2的order是2也就是说按照他们声明的顺序从1往上递增。
那么当系统中同时存在这么多过滤器的时候他们的执行顺序是什么样子的呢比如我现在同时定义了GlobalFilter1和GlobalFilter2还有配置了router1、router2、default1、default2的时候
Component
public class GlobalFilter1 implements GlobalFilter, Ordered {Overridepublic MonoVoid filter(ServerWebExchange exchange, GatewayFilterChain chain) {log.info(global1);return chain.filter(exchange);}Overridepublic int getOrder() {return 2;}
}还有GlobalFilter2
Component
public class GlobalFilter2 implements GlobalFilter, Ordered {Overridepublic MonoVoid filter(ServerWebExchange exchange, GatewayFilterChain chain) {log.info(global2);return chain.filter(exchange);}Overridepublic int getOrder() {return 1;}
}只需要在org.springframework.cloud.gateway.handler.FilteringWebHandler#handle()上打断点看一下即可
Override
public MonoVoid handle(ServerWebExchange exchange) {Route route exchange.getRequiredAttribute(GATEWAY_ROUTE_ATTR);// 拿到所有的路由过滤器包含了Default过滤器ListGatewayFilter gatewayFilters route.getFilters();// 拿到所有的Global过滤器ListGatewayFilter combined new ArrayList(this.globalFilters);// 先添加的Global过滤器然后再添加的路由过滤器combined.addAll(gatewayFilters);// TODO: needed or cached?AnnotationAwareOrderComparator.sort(combined);if (logger.isDebugEnabled()) {logger.debug(Sorted gatewayFilterFactories: combined);}// 在这一行打断点查看下combined之后的内容return new DefaultGatewayFilterChain(combined).filter(exchange);
}如下 从源码种可以看出来是先添加的Global过滤器然后再添加的路由过滤器从上面的截图也可以看出来GlobalFilter2排在最前面后面依次是default1、router1、GlobalFilter1、default2、router2。
可以继续在org.springframework.cloud.gateway.filter.factory.AddRequestHeaderGatewayFilterFactory#filter()方法和GlobalFilter上打断点看一下后续的执行顺序。
因此这些过滤器的执行顺序首先是根据order进行的排序如果order相同优先级是GlobalDefaultRouter。
3种过滤器的类型都不一样为啥可以在一块进行排序
Global过滤器是org.springframework.cloud.gateway.filter.GlobalFilter的子类但是路由过滤器和Default过滤器是org.springframework.cloud.gateway.filter.GatewayFilter的子类他们为啥可以放在一个集合中进行排序呢 还是看org.springframework.cloud.gateway.handler.FilteringWebHandler这个类它里面有一个loadFilters()方法
private static ListGatewayFilter loadFilters(ListGlobalFilter filters) {return filters.stream().map(filter - {// 把GlobalFilter适配成了GatewayFilterAdapterGatewayFilterAdapter gatewayFilter new GatewayFilterAdapter(filter);// 并且这里计算顺序的时候只是从Ordered接口取的if (filter instanceof Ordered) {int order ((Ordered) filter).getOrder();return new OrderedGatewayFilter(gatewayFilter, order);}return gatewayFilter;}).collect(Collectors.toList());
}
// GatewayFilterAdapter 就实现了GatewayFilter接口
private static class GatewayFilterAdapter implements GatewayFilter {private final GlobalFilter delegate;GatewayFilterAdapter(GlobalFilter delegate) {this.delegate delegate;}Overridepublic MonoVoid filter(ServerWebExchange exchange, GatewayFilterChain chain) {return this.delegate.filter(exchange, chain);}
}从上面的源码可以看出来gateway框架在启动的时候会把系统中所有的GlobalFilter适配成GatewayFilterAdapter 而GatewayFilterAdapter 是实现了GatewayFilter 接口的因此GlobalFilter也就适配成了GatewayFilter 因此他们是可以放到一个集合进行排序的。同时可以看到在获取GlobalFilter的order时候只是使用Ordered接口并没有使用Order注解。
结论
Global过滤器的顺序是由Ordered接口来定义Order不起作用。路由过滤器和Default过滤器的顺序是按照声明的顺序从1开始递增所有的Global过滤器、路由过滤器、Default过滤器最终会放到一个集合中按照order大小进行排序如果order值一样优先就是Global过滤器Default过滤器路由过滤器
ps以上测试结论基于spring-cloud.versionHoxton.SR10/spring-cloud.version