订购多个路由器功能

时间:2018-08-15 18:56:49

标签: spring spring-boot routes spring-webflux

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

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

问题有时是,/**会根据另一个命令的异想天开来阻塞另一个端点。

有没有办法订购单独的RouterFunctions或更好的方法来处理所有与其他物品不匹配的物品都进入特定路线?

2 个答案:

答案 0 :(得分:1)

Spring WebFlux正在收集所有RouterFunction bean,并使用RouterFunction::andOther将它们简化为一个(请参阅RouterFunctionMapping)。

因此,您可以像常规豆一样订购RouterFunction豆,其余的将由Spring WebFlux完成。

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

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

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

答案 1 :(得分:0)

我已经设计出一种利用RouterFunction具有add()函数将它们组合在一起的事实的解决方案。

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

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

我有多个,并且如果有一些冲突的路径(例如/**),那么其中一个是问号。

我决定将它们合并为一个RouterFunction,在这里我可以控制顺序。由于我不想在某个地方手动进行管理(即,如果我创建了一个新的Router类,我只是想让它自动获取)。

首先,我必须使常规路线不再是bean。我还需要一种简单的方法让Spring查找所有内容,因此我决定为它们进行扩展创建一个abstract class

看起来像这样:

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

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

priority使我可以覆盖它们的添加顺序(如果没关系,可以使用默认值)。较大的数字表示它将在以后加载。

在那之后,我将路由器类更改为Components,并使其不再吐出bean。像这样:

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

最后,我创建一个新的类和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) }
}

这似乎可以解决问题。现在,将按优先级顺序添加路由,因此对于可能有点贪婪(/**)的路由,我只需将该类的优先级设置为100即可使其居最后。