摘要: 原创出处 http://www.iocoder.cn/Spring-Cloud-Gateway/route-locator-route-custom-java/ 「芋道源码」欢迎转载,保留摘要,谢谢!
本文主要基于 Spring-Cloud-Gateway 2.0.X M4
阅读源码最好的方式,是使用 IDEA 进行调试 Spring Cloud Gateway 源码,不然会一脸懵逼。
1. 概述
本文主要分享如何使用 Java 实现自定义 RouteLocator。
ps :为什么这里强调 Java 呢?可以使用 Kotlin 实现自定义 RouteLocator ,在下一篇文章我们会详细分享。
首先我们来看一段示例程序,代码如下 :
import static org.springframework.cloud.gateway.filter.factory.GatewayFilters.addResponseHeader;
import static org.springframework.cloud.gateway.handler.predicate.RoutePredicates.host;
import static org.springframework.cloud.gateway.handler.predicate.RoutePredicates.path;
import static org.springframework.tuple.TupleBuilder.tuple;
@Bean
public RouteLocator customRouteLocator(ThrottleGatewayFilterFactory throttle) {
//@formatter:off
return Routes.locator()
// Route
.route("test")
.predicate(host("**.abc.org").and(path("/image/png")))
.addResponseHeader("X-TestHeader", "foobar")
.uri("http://httpbin.org:80")
// Route
.route("test2")
.predicate(path("/image/webp"))
.add(addResponseHeader("X-AnotherHeader", "baz"))
.uri("http://httpbin.org:80")
// Route
.route("test3")
.order(-1)
.predicate(host("**.throttle.org").and(path("/get")))
.add(throttle.apply(tuple().of("capacity", 1,
"refillTokens", 1,
"refillPeriod", 10,
"refillUnit", "SECONDS")))
.uri("http://httpbin.org:80")
.build();
////@formatter:on
}使用 Routes 创建了三个 Route 。
使用 RoutePredicates 创建每个 Route 的 Predicate 。
使用 GatewayFilters 创建每个 Route 的 GatewayFilter 。
推荐 Spring Cloud 书籍:
请支持正版。下载盗版,等于主动编写低级 BUG 。
程序猿DD —— 《Spring Cloud微服务实战》
两书齐买,京东包邮。
2. Routes
rg.springframework.cloud.gateway.route.Routes ,Java 自定义 RouteLocator Builder 。
Routes 内置多个 Builder 类,用于创建 Route 相关的各个元素 :
使用时,首先调用 Routes#locator() 方法,创建一个 LocatorBuilder 。代码如下 :
public static LocatorBuilder locator() {
return new LocatorBuilder();
}LocatorBuilder ,代码如下 :
public static class LocatorBuilder {
private List<Route> routes = new ArrayList<>();
public PredicateSpec route(String id) {
return new RouteSpec(this).id(id);
}
private void add(Route route) {
this.routes.add(route);
}
LocatorBuilder uri(Route.Builder builder, String uri) {
Route route = builder.uri(uri).build();
routes.add(route);
return this;
}
LocatorBuilder uri(Route.Builder builder, URI uri) {
Route route = builder.uri(uri).build();
routes.add(route);
return this;
}
public RouteLocator build() {
return () -> Flux.fromIterable(this.routes);
}
}routes属性,LocatorBuilder 已创建好的 Route 数组。#add()方法,添加已创建好的 Route 。#uri()方法,使用 Route.Builder 方法,创建 Route 并添加。#route()方法,不同于上面两个方法,首先创建 RouteSpec 对象,后调用RouteSpec#id(...)方法,创建 PredicateSpec 对象。为什么是这样的呢?Routes 里创建 Route 是有序的链式过程,如下如 :
绿线 :创建一个 Route.Builder 。
红线 :调用
LocatorBuilder#uri(uri)方法,创建 Route 并添加。后面,可以继续【绿线】,创建下一个 Route.Builder 。
#build()方法,创建自定义 RouteLocator 类。
RouteSpec / PredicateSpec / GatewayFilterSpec 实现上就是常见的 Builder 类,点击链接直接查看代码 :
3. RoutePredicates
org.springframework.cloud.gateway.handler.predicate.RoutePredicates ,RoutePredicates 工厂,其调用 RoutePredicateFactory 接口的实现类,创建各种 Predicate 。代码比较易懂,点击 链接 查看实现。
4. GatewayFilters
org.springframework.cloud.gateway.filter.factory.GatewayFilters ,GatewayFilter 工厂,其调用 GatewayFilterFactory 接口的实现类,创建各种 GatewayFilter 。代码比较易懂,点击 链接 查看实现。