我正在尝试将一些项目从 Spring Reactor 迁移到 kotlin 协程。我有一些基于 spring webflux 的 Controller ,如下所示:
@RestController
class Controller(val productRepository: ProductsRepository) {
@GetMapping("/product")
fun find(@RequestParam id: String): Mono<Product> {
return productRepository.findById(id)
}
}
该 Controller 使用响应式(Reactive) Spring 数据存储库:
@Repository
interface ProductsRepository : ReactiveMongoRepository<Product, String>
根据此官方文档 - https://docs.spring.io/spring/docs/5.2.0.M1/spring-framework-reference/languages.html#how-reactive-translates-to-coroutines , 我的函数
find
在 Controller 中应转换为 suspend fun
并且此函数应返回 Product 类的实例,而不是 Product 的响应式(Reactive) Mono 包装器。类似的东西:@RestController
class Controller(val productRepository: ProductsRepository) {
@GetMapping("/product")
suspend fun find(@RequestParam id: String): Product {
return productRepository.findById(id)
}
}
但是我的 productRepository 处理 Mono 和 Flux,而不是挂起的函数。在这种情况下,我应该如何正确使用 spring 数据抽象?
最佳答案
这可以通过有用的 kotlinx-coroutines-reactor
来实现。帮助程序库,为项目 react 器提供有用的扩展方法 Publisher
帮助转换 Mono
或 Flux
到 kotlin 协程。
首先添加依赖
<dependency>
<groupId>org.jetbrains.kotlinx</groupId>
<artifactId>kotlinx-coroutines-reactor</artifactId>
</dependency>
(如果您使用 spring-boot,则不必指定版本,因为它会为您管理它)
您现在可以使用
kotlinx.coroutines.reactive.awaitFirstOrNull
转换 Mono<Product>
至 Product?
并“等待”结果。@RestController
class Controller(val productRepository: ProductsRepository) {
@GetMapping("/product")
suspend fun find(@RequestParam id: String): Product? {
return productRepository.findById(id).awaitFirstOrNull()
}
}
关于spring - 如何将 kotlin 协程与响应式 Spring 数据一起使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60844448/