Java 流式路由 API (Fluent Java Routes API)
为了支持在 Java 中进行简易配置,RouteLocatorBuilder Bean 提供了一套流式 API (Fluent API)。以下清单展示了它的工作方式:
GatewaySampleApplication.java
java
// 静态导入 GatewayFilters 和 RoutePredicates 中的方法
@Bean
public RouteLocator customRouteLocator(RouteLocatorBuilder builder, ThrottleGatewayFilterFactory throttle) {
return builder.routes()
.route(r -> r.host("**.abc.org").and().path("/image/png")
.filters(f ->
f.addResponseHeader("X-TestHeader", "foobar"))
.uri("http://httpbin.org:80")
)
.route(r -> r.path("/image/webp")
.filters(f ->
f.addResponseHeader("X-AnotherHeader", "baz"))
.uri("http://httpbin.org:80")
.metadata("key", "value")
)
.route(r -> r.order(-1)
.host("**.throttle.org").and().path("/get")
.filters(f -> f.filter(throttle.apply(1,
1,
10,
TimeUnit.SECONDS)))
.uri("http://httpbin.org:80")
.metadata("key", "value")
)
.build();
}这种风格还允许进行更多自定义的断言判断。由 RouteDefinitionLocator Bean 定义的断言通常通过逻辑 and 进行组合。而通过使用流式 Java API,你可以在 Predicate 类上灵活使用 and()、or() 和 negate()(取反)操作符。
补充教学 —— YAML 还是 Java DSL?
在 Spring Cloud Gateway 中,你可以选择在 application.yml 中配置路由,也可以在 Java 代码中配置。它们各有千秋:
1. YAML 配置 (配置文件派):
- 优点:热更新友好(配合外部配置中心)、无需重新编译代码、可读性强、适合标准路由。
- 逻辑限制:断言之间默认只能是
and关系。如果想表达“路径是 A 或者 路径是 B”,在 YAML 中写起来比较别扭。
2. Java DSL 配置 (代码派):
- 优点:
- 强大的逻辑组合:可以轻松使用
.or()和.negate()。比如:“如果 Host 是 abc.com 且路径不以 /private 开头”。 - 动态性:可以根据内存中的变量、复杂的业务逻辑来动态构建路由。
- 类型安全:有 IDE 的代码补全,写错参数名会报错。
- 集成自定义过滤器:如示例中,你可以直接注入自定义的
GatewayFilterFactory并通过apply方法调用它。
- 强大的逻辑组合:可以轻松使用
3. 语法小细节:
- 在 Java DSL 中,你可以看到
.route(r -> r.host(...).and().path(...)),这里的.and()是可选的,直接连续写断言默认就是and关系。 - 注意到示例中的
.order(-1),这在代码中非常直观,用来置顶路由的优先级。
最佳实践:
- 90% 的场景建议用 YAML,因为配置更直观,方便后期维护和热切换。
- 复杂的逻辑判断或需要对过滤器进行深度定制时,选择 Java DSL。