You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Spring Cloud Gateway中为Route.Builder设置断言?

Spring Cloud Gateway中Route.Builder添加断言的疑问

我不会展开过多细节(相关性不强且代码量较大),以下是我编写的接口:

@FunctionalInterface
public interface RouteProcessor {
    // DocumentedEndpoint是我封装服务暴露端点的自定义类
    Route.Builder process(Route.Builder routeInConstruction, DocumentedEndpoint endpoint);
}

它的使用方式如下(仅为基础思路,非最终代码):

private void buildAndAddRoutesFrom(List<? extends DocumentedEndpoint> endpoints) {
    for (DocumentedEndpoint endpoint : endpoints) {
        Route.Builder routeBuilder = Route.builder();
        for (RouteProcessor routeProcessor : routeProcessors) {
            routeBuilder = routeProcessor.process(routeBuilder, endpoint);
        }
        routeFlux = routeFlux.concatWith(Mono.just(routeBuilder.build())); // 此写法有待商榷,但暂不讨论
    }
}

以上内容并非重点。重点是我觉得Spring Cloud Gateway的源码设计存在优化空间,尤其是我不知道如何为构建中的Route添加断言。例如,假设我已创建了断言,该如何将其传入?

@Bean
public RouteProcessor authenticationRouteProcessor() {
    return (routeInConstruction, endpoint) -> {
            AsyncPredicate<ServerWebExchange> newPredicate = AsyncPredicate.from(serverWebExchange -> serverWebExchange
                    .getRequest()
                    .getPath()
                    .toString()
                    .startsWith("/api/v1"));

            AsyncPredicate<ServerWebExchange> compoundPredicate = routeInConstruction.getPredicate().and(predicate);

            // 接下来该怎么做?

如何在Spring Cloud Gateway中为Route.Builder设置断言?难道只能通过调用这个私有构造方法来传入吗?

// 来自Route.AbstractBuilder
public Route build() {
    Assert.notNull(this.id, "id can not be null");
    Assert.notNull(this.uri, "uri can not be null");
    AsyncPredicate<ServerWebExchange> predicate = getPredicate();
    Assert.notNull(predicate, "predicate can not be null");

    // Route包含断言,但Route.Builder却没有!
    return new Route(this.id, this.uri, this.order, predicate, this.gatewayFilters, this.metadata);
}

Gateway的设计让我感到意外。我知道有个不错的and()方法可以用作设置器:

public Builder and(Predicate<ServerWebExchange> predicate) {
    Assert.notNull(this.predicate, "can not call and() on null predicate");
    this.predicate = this.predicate.and(predicate);
    return this;
}

但这种设置本质上是方法的副作用,让我觉得这更像是一种权宜之计,而非库使用者应采用的正规方式。更重要的是,我该如何向已有的断言中添加新断言?由于空值检查,初始断言应该已初始化,但以下写法无法生效:

@Bean
public RouteProcessor basicPredicateProcessor() {
    return (routeInConstruction, endpoint) -> {
        routeInConstruction.and(serverWebExchange -> serverWebExchange
                .getRequest()
                .getPath()
                .toString()
                .startsWith("/api/v1"));
        return routeInConstruction;
    };
}

希望情况没有那么糟,是我遗漏了某些关键的源码片段。


内容的提问来源于stack exchange,提问作者Sergey Zolotarev

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 23:47:44