008-spring cloud gateway-路由谓词RoutePredicate、RoutePredicateFactory
一、概述
Spring Cloud Gateway将路由作为Spring WebFlux HandlerMapping基础结构的一部分进行匹配。 Spring Cloud Gateway包含许多内置的Route Predicate Factories。所有这些谓词都匹配HTTP请求的不同属性。多路线谓词工厂可以组合,并通过逻辑and。
路由选择是通过Predicate函数式接口进行判断当前路由是否满足给定条件。
附注:关于jdk8的Predicate
Predicate<T> 接受一个输入参数,返回一个布尔值结果。该接口包含多种默认方法来将Predicate组合成其他复杂的逻辑(比如:与,或,非)。可以用于接口请求参数校验、判断新老数据是否有变化需要进行更新操作。
add--与、or--或、negate--非
boolean test(T t); 判断
Predicate<T> and(Predicate<? super T> other) 接收一个Predicate类型,也就是将传入的条件和当前条件以并且(AND)的关系组合
Predicate<T> or(Predicate<? super T> other)接收一个Predicate类型,也就是将传入的条件和当前条件以或(OR)的关系组合
更多参看:https://www.cnblogs.com/bjlhx/p/9711292.html
1.1、路由谓词创建及使用
1️⃣、加载路由中的Predicate
/**
* 返回组合的谓词
* @param routeDefinition
* @return
*/
private Predicate<ServerWebExchange> combinePredicates(RouteDefinition routeDefinition) {
//获取RouteDefinition中的PredicateDefinition集合
List<PredicateDefinition> predicates = routeDefinition.getPredicates(); Predicate<ServerWebExchange> predicate = lookup(routeDefinition, predicates.get(0)); for (PredicateDefinition andPredicate : predicates.subList(1, predicates.size())) {
Predicate<ServerWebExchange> found = lookup(routeDefinition, andPredicate);
//返回一个组合的谓词,表示该谓词与另一个谓词的短路逻辑AND
predicate = predicate.and(found);
} return predicate;
} /**
* 获取一个谓语定义(PredicateDefinition)转换的谓语
* @param route
* @param predicate
* @return
*/
@SuppressWarnings("unchecked")
private Predicate<ServerWebExchange> lookup(RouteDefinition route, PredicateDefinition predicate) {
//获取谓语创建工厂
RoutePredicateFactory<Object> factory = this.predicates.get(predicate.getName());
if (factory == null) {
throw new IllegalArgumentException("Unable to find RoutePredicateFactory with name " + predicate.getName());
}
//获取参数
Map<String, String> args = predicate.getArgs();
if (logger.isDebugEnabled()) {
logger.debug("RouteDefinition " + route.getId() + " applying "
+ args + " to " + predicate.getName());
} //组装参数
Map<String, Object> properties = factory.shortcutType().normalize(args, factory, this.parser, this.beanFactory);
//构建创建谓语的配置信息
Object config = factory.newConfig();
ConfigurationUtils.bind(config, properties,
factory.shortcutFieldPrefix(), predicate.getName(), validator);
if (this.publisher != null) {
this.publisher.publishEvent(new PredicateArgsEvent(this, route.getId(), properties));
}
//通过谓语工厂构建谓语
return factory.apply(config);
}
- 获取路由定义(routeDefinition)所有的谓语定位(PredicateDefinition)
- 以此根据谓语定义(PredicateDefinition)查找谓语对于的创建工厂(RoutePredicateFactory) 创建谓语
- 通过 Predicate<T>接口 and方法合并谓语集合返回一个新的复合谓语
2️⃣、使用路由Predicate判断路由是否可用
在Spring-Cloud-Gateway之请求处理流程里,在handlerMapping中通过路由定位器获取所有路由,并过滤掉谓语判断失败的路由,最终获取满足条件的路由
protected Mono<Route> lookupRoute(ServerWebExchange exchange) {
//通过路由定位器获取路由信息
return this.routeLocator.getRoutes()
.filter(route -> {
exchange.getAttributes().put(GATEWAY_PREDICATE_ROUTE_ATTR, route.getId());
//返回通过谓语过滤的路由信息
return route.getPredicate().test(exchange);
});
}
通过上面两步可以看到了整个路由的条件创建以及使用的地方以及流程,Spring-Cloud-Gateway通过Predicate接口完成简单条件组合以及判断。
1.2、RoutePredicateFactory 路由谓词工厂

按照子类功能划分:
1️⃣、MethodRoutePredicateFactory
/**
* 请求方式(GET,POST,DEL,PUT)校验匹配创建工厂
*/
public class MethodRoutePredicateFactory extends AbstractRoutePredicateFactory<MethodRoutePredicateFactory.Config> { public static final String METHOD_KEY = "method";
@Override
public Predicate<ServerWebExchange> apply(Config config) {
return exchange -> {
//获取当前请求的HttpMethod
HttpMethod requestMethod = exchange.getRequest().getMethod();
//校验请求HttpMethod与配置是否一致
return requestMethod == config.getMethod();
};
} public static class Config {
/**
* http 请求Method
*/
private HttpMethod method; public HttpMethod getMethod() {
return method;
} public void setMethod(HttpMethod method) {
this.method = method;
}
}
}
配置示例
spring:
cloud:
gateway:
routes:
# =====================================
- id: method_route
uri: http://example.org
predicates:
- Method=GET
过程:
- Method=GET 会被解析成PredicateDefinition对象 (name =Method ,args= GET)
- 通过PredicateDefinition的Name找到MethodRoutePredicateFactory工厂
- 通过 PredicateDefinition 的args 创建Config对象(HttpMethod=GET)
- 通过 MethodRoutePredicateFactory工厂的apply方法传入config创建Predicate对象。
1.3、全部谓词配置
1.3.1、After Route Predicate Factory
此谓词匹配当前日期时间之后发生的请求。
application.yml
spring:
cloud:
gateway:
routes:
- id: after_route
uri: http://example.org
predicates:
- After=2017-01-20T17:42:47.789-07:00[America/Denver]
1.3.2、Before Route Predicate Factory
此谓词匹配在当前日期时间之前发生的请求。
application.yml
spring:
cloud:
gateway:
routes:
- id: before_route
uri: http://example.org
predicates:
- Before=2017-01-20T17:42:47.789-07:00[America/Denver]
1.3.3、Between Route Predicate Factory
此谓词匹配datetime1之后和datetime2之前发生的请求。 datetime2参数必须在datetime1之后。
application.yml
spring:
cloud:
gateway:
routes:
- id: between_route
uri: http://example.org
predicates:
- Between=2017-01-20T17:42:47.789-07:00[America/Denver], 2017-01-21T17:42:47.789-07:00[America/Denver]
1.3.4、Cookie Route Predicate Factory
Cookie Route Predicate Factory有两个参数,cookie名称和正则表达式。此谓词匹配具有给定名称且值与正则表达式匹配的cookie。
application.yml
spring:
cloud:
gateway:
routes:
- id: cookie_route
uri: http://example.org
predicates:
- Cookie=chocolate, ch.p
此路由匹配请求有一个名为chocolate的cookie,其值与ch.p正则表达式匹配。
1.3.5、Header Route Predicate Factory
Header Route Predicate Factory有两个参数,标题名称和正则表达式。此谓词与具有给定名称且值与正则表达式匹配的标头匹配。
application.yml
spring:
cloud:
gateway:
routes:
- id: header_route
uri: http://example.org
predicates:
- Header=X-Request-Id, \d+
如果请求具有名为X-Request-Id的标头,则该路由匹配,其值与\ d +正则表达式匹配(具有一个或多个数字的值)。
1.3.6、Host Route Predicate Factory
Host Route Predicate Factory采用一个参数:主机名模式。该模式是一种Ant样式模式“.”作为分隔符。此谓词匹配与模式匹配的Host标头。
application.yml
spring:
cloud:
gateway:
routes:
- id: host_route
uri: http://example.org
predicates:
- Host=**.somehost.org
如果请求的主机头具有值www.somehost.org或beta.somehost.org,则此路由将匹配。
1.3.7、Method Route Predicate Factory
Method Route Predicate Factory采用一个参数:要匹配的HTTP方法。
spring:
cloud:
gateway:
routes:
- id: method_route
uri: http://example.org
predicates:
- Method=GET
1.3.8、Path Route Predicate Factory
spring:
cloud:
gateway:
routes:
- id: host_route
uri: http://example.org
predicates:
- Path=/foo/{segment}
/foo/1
or /foo/bar
.
1.3.9、Query Route Predicate Factory
Query Route Predicate Factory有两个参数:一个必需的参数和一个可选的正则表达式。
spring:
cloud:
gateway:
routes:
- id: query_route
uri: http://example.org
predicates:
- Query=baz
如果请求包含baz查询参数,则此路由将匹配。
spring:
cloud:
gateway:
routes:
- id: query_route
uri: http://example.org
predicates:
- Query=foo, ba.
如果请求包含其值与ba匹配的foo查询参数,则此路由将匹配。 regexp,所以bar和baz匹配。
1.3.10、RemoteAddr Route Predicate Factory
RemoteAddr Route Predicate Factory采用CIDR符号(IPv4或IPv6)字符串的列表(最小值为1),例如, 192.168.0.1/16(其中192.168.0.1是IP地址,16是子网掩码)。
spring:
cloud:
gateway:
routes:
- id: remoteaddr_route
uri: http://example.org
predicates:
- RemoteAddr=192.168.1.1/24
如果请求的远程地址是例如192.168.1.10,则此路由将匹配。
008-spring cloud gateway-路由谓词RoutePredicate、RoutePredicateFactory的更多相关文章
- SpringCloud无废话入门05:Spring Cloud Gateway路由、filter、熔断
1.什么是路由网关 截至目前为止的例子中,我们创建了一个service,叫做:HelloService,然后我们把它部署到了两台服务器(即提供了两个provider),然后我们又使用ribbon将其做 ...
- Spring Cloud Gateway - 路由法则
1. After Route Predicate Factory 输入一个参数:时间,匹配该时间之后的请求,示例配置: spring: cloud: gateway: routes: - id: af ...
- Spring Cloud Alibaba学习笔记(16) - Spring Cloud Gateway 内置的路由谓词工厂
Spring Cloud Gateway路由配置的两种形式 Spring Cloud Gateway的路由配置有两种形式,分别是路由到指定的URL以及路由到指定的微服务,在上文博客的示例中我们就已经使 ...
- spring cloud gateway 深入了解 - Predicate
文章来源 spring cloud gateway 通过谓词(Predicate)来匹配来自用户的请求 为了方便,使用postman测试不同的谓词的效果 路径谓词(Predicate)—— 最简单的谓 ...
- 看完就会的Spring Cloud Gateway
在前面几节,我给大家介绍了当一个系统拆分成微服务后,会产生的问题与解决方案:服务如何发现与管理(Nacos注册中心实战),服务与服务如何通信(Ribbon, Feign实战) 今天我们就来聊一聊另一个 ...
- Spring Cloud Gateway 没有链路信息,我 TM 人傻了(上)
本系列是 我TM人傻了 系列第五期[捂脸],往期精彩回顾: 升级到Spring 5.3.x之后,GC次数急剧增加,我TM人傻了 这个大表走索引字段查询的 SQL 怎么就成全扫描了,我TM人傻了 获取异 ...
- Spring Cloud Gateway 没有链路信息,我 TM 人傻了(中)
本系列是 我TM人傻了 系列第五期[捂脸],往期精彩回顾: 升级到Spring 5.3.x之后,GC次数急剧增加,我TM人傻了 这个大表走索引字段查询的 SQL 怎么就成全扫描了,我TM人傻了 获取异 ...
- Spring Cloud Gateway夺命连环10问?
大家好,我是不才陈某~ 最近有很多小伙伴私信我催更 <Spring Cloud 进阶>,陈某也总结了一下,最终原因就是陈某之前力求一篇文章将一个组件重要知识点讲透,这样导致了文章篇幅很长, ...
- Spring Cloud Gateway(六):路由谓词工厂 RoutePredicateFactory
本文基于 spring cloud gateway 2.0.1 1.简介 Spring Cloud Gateway 创建 Route 对象时, 使用 RoutePredicateFactory 创建 ...
- Spring Cloud Alibaba学习笔记(17) - Spring Cloud Gateway 自定义路由谓词工厂
在前文中,我们介绍了Spring Cloud Gateway内置了一系列的路由谓词工厂,但是如果这些内置的路由谓词工厂不能满足业务需求的话,我们可以自定义路由谓词工厂来实现特定的需求. 例如有某个服务 ...
随机推荐
- [OpenGL]用OpenGL制作动画
//在窗口内绘制一个移动的矩形 /*我们通常还可以用OpenGL程序创建动画效果,这里我们利用前面的例子,绘制正方形,并使这个正方形在窗口的边框反弹.这里需要创建一个循环,在每次调用显示回调函数之前改 ...
- Qt编写数据库通用翻页demo(开源)
在Qt与数据库结合编程的过程中,记录一多,基本上都需要用到翻页查看记录,翻页有个好处就是可以减轻显示数据的表格的压力,不需要一次性将数据库表的记录全部显示,也基本上没有谁在一页上需要一次性显示所有记录 ...
- 用Ant给Unity3D导出Eclipse工程打包APK
我们经常需要出完apk后,告诉我们改版本号,或者包名什么的,但是每次打包时间又很长.索性我们就出一个eclipse工程,然后用ant自动打包. 1.设置环境变量 2.生成build.xml文件 and ...
- Android 源码下载,国内 镜像
AOSP(Android) 镜像使用帮助 https://lug.ustc.edu.cn/wiki/mirrors/help/aosp 首先下载 repo 工具. mkdir ~/bin PATH=~ ...
- Notepad++如何关闭最近打开的文件的历史记录功能
Notepad++是Windows 操作系统下的一套非常有特色的自由软件的纯文字编辑器(许可证:GPL),有完整的中文化接口及支持多国语言编写的 功能(UTF8 技术).它的功能比Windows中的N ...
- Win8安装msi程序出现2502、2503错误解决方法
在Win8中,在安装msi安装包的时候常常会出现代码为2502.2503的错误.其实这种错误是由于安装权限不足造成的,因为这种msi的安装包不像其他exe的安装程序, 在安装包上点击"右键& ...
- s3接口认证说明
S3 Authorization太绕,太头痛,下面解释说明: XS3 REST API基于HMAC(哈希消息身份验证码)密钥使用自定义HTTP方案进行身份验证.要对请求进行身份验证,您首先需要合并请求 ...
- Android aapt使用小结
Android打包成Apk后,其实是一个压缩文件,我们用winrar打开也能看到里面的文件结构.还能看到AndroidManifest.但是里面的内容有点问题. 不知道是因为加密还是Android就是 ...
- Spring Cloud Eureka 服务治理机制
服务提供者 服务提供者在启动的时候会通过发送REST请求的方式将自己注册到Eureka Server上,同时带上了自身服务的一些元数据信息.Eureka Server 接收到这个RE ...
- Qt Package Project 打包发布程序
在Qt项目开发完成后,我们想将项目打包发布成一个可执行文件,需要做如下步骤: 首先,将项目中的release文件中的可执行文件拷到一个新建的文件夹中,例如project.exe,用Qt自带的生成必备的 ...