订购多个 RouterFunction

Ordering multiple RouterFunctions

我有多个 RouterFunctions 注册为 beans(每段代码一个)。

其中之一是 /** 用于 React 的动态路由。基本上,如果没有其他路线匹配,我希望它去那个。

问题是有时,根据使用顺序的突发奇想,/** 会阻塞另一个端点。

有没有办法订购单独的 RouterFunctions 或更好的方法来处理所有不匹配的东西都转到特定路线?

我已经制定了一个解决方案,它利用 RouterFunction 有一个 add() 函数将它们组合在一起。

首先,我有 RouterFunction 个看起来像这样的豆子:

@Configuration
class MyRouter {
  @Bean
  fun myRoutes(myHandler: MyHandler): RouterFunction<ServerResponse>
    = router {
      GET("/path", myHandler::handlePath)
    }
}

我有多个这样的,如果有一些冲突的路径(比如 /**),哪一个 运行 有点问号。

我决定将它们合并为一个 RouterFunction,以便我可以控制顺序。因为我不想在某个地方手动管理这些(即,如果我制作了一个新路由器 class,我只是希望它自动拾取)。

首先,我必须让我的正常路线不再是豆类。我还需要一种简单的方法让 Spring 找到它们,所以我决定创建一个 abstract class 供它们扩展。

看起来像这样:

abstract class RouterConfig {
  open val priority: Int = 0 // higher number, later in list

  open val routes: RouterFunction<ServerResponse>
    get() = TODO()
}

priority 让我可以覆盖它们的添加顺序(如果无关紧要,默认值就可以)。数字越大表示稍后加载。

之后,我把我的路由器 classes 改成 Components 让他们不再吐豆子了。像这样:

@Configuration
  class MyRouter(
    private val myHandler: MyHandler
  ) {
    override val routes: RouterFunction<ServerResponse>
      get() = router {
        GET("/path", myHandler::handlePath)
      }
}

最后,我创建了一个新的 class 和将它们全部收集起来的 bean:

@Configuration
class AppRouter {
  @Bean
  fun appRoutes(routerConfigs: List<RouterConfig>): RouterFunction<ServerResponse>
    = routerConfigs.sortedBy { it.priority }
      .map { it.routes }
      .reduce { r, c -> r.add(c) }
}

这似乎起到了作用。现在路由将按优先级顺序添加,所以对于可能有点贪心的路由 (/**),我只是将 class 的优先级设置为 100 使其排在最后.

Spring WebFlux 正在收集所有 RouterFunction bean 并使用 RouterFunction::andOther 将它们缩减为一个(参见 RouterFunctionMapping)。

因此,您只需将 RouterFunction bean 作为常规 bean 订购,Spring WebFlux 将完成剩下的工作。

@Bean
@Order(1)
public RouterFunction first() {
  //
}

@Bean
@Order(2)
public RouterFunction second() {
  //
}

@Bean
@Order(3)
public RouterFunction third() {
  //
}