鱼C论坛

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

spring gateway 通过RouteDefinitionWriter 动态添加路由

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

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

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

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

  2. import reactor.core.publisher.Mono;

  3. /**
  4. * @author Spencer Gibb
  5. */
  6. public interface RouteDefinitionWriter {

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

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

  9. }
复制代码

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

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

  17. import java.util.LinkedHashMap;
  18. import java.util.Map;

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

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

  23. import static java.util.Collections.synchronizedMap;

  24. /**
  25. * @author Spencer Gibb
  26. */
  27. public class InMemoryRouteDefinitionRepository implements RouteDefinitionRepository {

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

  29.         @Override
  30.         public Mono<Void> save(Mono<RouteDefinition> route) {
  31.                 return route.flatMap(r -> {
  32.                         if (ObjectUtils.isEmpty(r.getId())) {
  33.                                 return Mono.error(new IllegalArgumentException("id may not be empty"));
  34.                         }
  35.                         routes.put(r.getId(), r);
  36.                         return Mono.empty();
  37.                 });
  38.         }

  39.         @Override
  40.         public Mono<Void> delete(Mono<String> routeId) {
  41.                 return routeId.flatMap(id -> {
  42.                         if (routes.containsKey(id)) {
  43.                                 routes.remove(id);
  44.                                 return Mono.empty();
  45.                         }
  46.                         return Mono.defer(() -> Mono.error(new NotFoundException("RouteDefinition not found: " + routeId)));
  47.                 });
  48.         }

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

  54. }
复制代码


我看网上很多文章在调用 save方法添加路由的时候,调用了subscribe
  1. routeDefinitionWriter.save(Mono.just(definition)).subscribe();
复制代码

但是在调用delete方法删除路由的时候,没有调用subscribe
  1. this.routeDefinitionWriter.delete(Mono.just(definition.getId()));
  2.                         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-4-28 08:56

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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