我正在尝试将某些项目从Spring Reactor迁移到Kotlin协程。我有一些基于spring webflux的控制器,例如:
@RestController
class Controller(val productRepository: ProductsRepository) {
@GetMapping("/product")
fun find(@RequestParam id: String): Mono<Product> {
return productRepository.findById(id)
}
}
此控制器使用反应性弹簧数据存储库:
@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
应该转换为suspend fun
,并且此函数应该返回Product类的实例,而不是Product的反应式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
帮助程序库来实现。
首先添加依赖项
<dependency>
<groupId>org.jetbrains.kotlinx</groupId>
<artifactId>kotlinx-coroutines-reactor</artifactId>
</dependency>
((如果使用spring-boot,则不必指定版本,因为它会自动提供它)
这为项目反应堆Publisher
提供了有用的扩展方法,以帮助在将Mono
或Flux
转换为Kotlin协程suspend fun
之间进行转换。
您现在可以使用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()
}
}