鱼C论坛

 找回密码
 立即注册
查看: 375|回复: 3

spring gateway 通过RouteDefinitionWriter 动态添加路由

[复制链接]
发表于 2024-2-15 13:59:07 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
package org.springframework.cloud.gateway.route;

import reactor.core.publisher.Mono;

/**
 * @author Spencer Gibb
 */
public interface RouteDefinitionWriter {

        Mono<Void> save(Mono<RouteDefinition> route);

        Mono<Void> delete(Mono<String> routeId);

}
上面是这个接口的代码,默认的实现类是
/*
 * Copyright 2013-2020 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.springframework.cloud.gateway.route;

import java.util.LinkedHashMap;
import java.util.Map;

import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

import org.springframework.cloud.gateway.support.NotFoundException;
import org.springframework.util.ObjectUtils;

import static java.util.Collections.synchronizedMap;

/**
 * @author Spencer Gibb
 */
public class InMemoryRouteDefinitionRepository implements RouteDefinitionRepository {

        private final Map<String, RouteDefinition> routes = synchronizedMap(new LinkedHashMap<String, RouteDefinition>());

        @Override
        public Mono<Void> save(Mono<RouteDefinition> route) {
                return route.flatMap(r -> {
                        if (ObjectUtils.isEmpty(r.getId())) {
                                return Mono.error(new IllegalArgumentException("id may not be empty"));
                        }
                        routes.put(r.getId(), r);
                        return Mono.empty();
                });
        }

        @Override
        public Mono<Void> delete(Mono<String> routeId) {
                return routeId.flatMap(id -> {
                        if (routes.containsKey(id)) {
                                routes.remove(id);
                                return Mono.empty();
                        }
                        return Mono.defer(() -> Mono.error(new NotFoundException("RouteDefinition not found: " + routeId)));
                });
        }

        @Override
        public Flux<RouteDefinition> getRouteDefinitions() {
                Map<String, RouteDefinition> routesSafeCopy = new LinkedHashMap<>(routes);
                return Flux.fromIterable(routesSafeCopy.values());
        }

}

我看网上很多文章在调用 save方法添加路由的时候,调用了subscribe
routeDefinitionWriter.save(Mono.just(definition)).subscribe();
但是在调用delete方法删除路由的时候,没有调用subscribe
this.routeDefinitionWriter.delete(Mono.just(definition.getId()));
                        this.routeDefinitionWriter.save(Mono.just(definition)).subscribe();
这是为什么啊?响应式流不是在调用subscribe之后才可以执行吗?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2024-2-15 13:59:16 | 显示全部楼层
是的,响应式流需要在调用subscribe之后才能执行。但是在上面的代码中,保存(save)方法返回的是一个Mono,而删除(delete)方法返回的也是一个Mono。在这里调用subscribe的作用是订阅这个Mono,并且触发其中的逻辑执行。

对于保存方法,调用subscribe会触发保存路由的逻辑,因此需要调用subscribe来确保路由被保存。

而对于删除方法,只需要订阅这个Mono,而不需要触发其中的逻辑执行。因为删除操作是在删除路由时被执行的,而不是在订阅时执行的。所以不需要调用subscribe来执行删除操作。

总结来说,保存操作需要调用subscribe来触发保存逻辑的执行,而删除操作只需要订阅这个Mono即可,无需额外的调用subscribe。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2024-2-15 14:03:14 | 显示全部楼层
FishC 发表于 2024-2-15 13:59
是的,响应式流需要在调用subscribe之后才能执行。但是在上面的代码中,保存(save)方法返回的是一个Mono ...

总结来说,保存操作需要调用subscribe来触发保存逻辑的执行,而删除操作只需要订阅这个Mono即可,无需额外的调用subscribe。
这句话什么意思?
响应式流中的订阅和执行有什么区别?
为什么保存需要执行而删除不需要执行?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2024-2-15 14:03:25 | 显示全部楼层
Max472 发表于 2024-02-15 14:03
总结来说,保存操作需要调用subscribe来触发保存逻辑 ...


抱歉,前一句话表述不准确。在响应式编程中,订阅(subscribe)与执行是相同的意思。当你调用.subscribe()方法时,你实际上是在订阅这个响应式流,并且触发其中的逻辑执行。

所以准确来说,保存操作和删除操作都需要进行订阅(即调用.subscribe()方法),以触发操作的执行。无论是保存(save)还是删除(delete),只有当你调用.subscribe()方法时,才会执行相关的逻辑。

因此,在调用保存操作的时候,需要调用.subscribe()方法,以确保保存逻辑被执行。而在调用删除操作的时候,也同样需要调用.subscribe()方法,以触发删除逻辑的执行。对于删除操作,无论是调用.subscribe()方法还是不调用.subscribe()方法,都不会执行删除操作。

综上所述,无论是保存操作还是删除操作,在调用时都需要使用.subscribe()方法来触发逻辑的执行。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-9-21 00:44

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表