带有Kotlin协程的Spring Boot休息服务 [英] Spring Boot Rest Service With Kotlin Coroutines

查看:226
本文介绍了带有Kotlin协程的Spring Boot休息服务的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在Kotlin中编写Spring Boot Rest Service.我想使用协程作为Webflux的替代方案,以实现非阻塞异步行为.我正在使用Spring Boot 2.1,并且知道我无法实现真正​​的非阻塞行为,因为我在Controller处进行了阻塞.但是,到目前为止,我还可以接受,直到Spring Boot 2.2普遍可用为止.

I am writing a Spring Boot Rest Service in Kotlin. I want to use coroutines as an alternative to Webflux to achieve non-blocking asynchronous behavior. I am using Spring Boot 2.1 and know that I cannot achieve true non-blocking behavior because I am blocking at Controller. However, I am okay with that for now till the time Spring Boot 2.2 is generally available.

我的应用程序是三层的,即Controller-> Service-> Repository.在存储库中,我正在调用其他服务,即网络调用,并将该方法标记为暂停".

My app is three-layered ie Controller->Service->Repository. In repository, I am calling other services ie network calls and have marked the method as suspend.

我想确保这是正确的方法,此外,在ResourceService内部进行的调用以暂停乐趣会阻塞调用者线程吗?

I want to ensure if this is the right approach, additionally, does call to suspend fun inside ResourceService blocks the caller thread?

还在阅读 https://medium.com/@elizarov/Roman Elizarov撰写的blocking-threads-suspending-coroutines-d33e11bf4761 我不确定我是否应该将withContext与我所有的暂挂函数一起使用?

Also after reading https://medium.com/@elizarov/blocking-threads-suspending-coroutines-d33e11bf4761 by Roman Elizarov I am not sure if I should use withContext along with all of my suspending functions?

package my.springbootapp

import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.asCoroutineDispatcher
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.withContext
import mu.KotlinLogging
import org.springframework.boot.SpringApplication
import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.stereotype.Repository
import org.springframework.stereotype.Service
import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.PathVariable
import org.springframework.web.bind.annotation.RestController
import java.util.concurrent.Executors

val logger = KotlinLogging.logger { }

@SpringBootApplication
class App

fun main(args: Array<String>) {
    SpringApplication.run(App::class.java, *args)
}

@RestController
class Controller(private val resourceService: ResourceService) {
    private val dispatcher = Executors.newFixedThreadPool(5).asCoroutineDispatcher()

    @GetMapping("/resource/{id}")
    fun getResource(@PathVariable("id") id: String) = runBlocking(dispatcher) {
        resourceService.get(id).also { logger.info { Thread.currentThread().name + "Returning $it" } }
    }
}

@Service
class ResourceService(private val networkResourceRepository: NetworkResourceRepository) {

    suspend fun get(id: String): Resource {
        logger.info { Thread.currentThread().name + "Getting resource" }
        return networkResourceRepository.get(id)
    }
}

@Repository
class NetworkResourceRepository {
    suspend fun get(id: String): Resource = withContext(Dispatchers.IO) {
        logger.info { Thread.currentThread().name + "Getting resource from n/w" }
        //IO operation
        Resource("resource data")
    }
}

data class Resource(val data: String)

推荐答案

我认为您应该将协程与WebFlux一起使用,但不能代替WebFlux.要将WebFlux与协程一起使用,必须添加WebFlux-Wrapper,这会使WebFlux可挂起. WebFlux +协同程序示例 协程本身不会使您的代码无阻塞,协程的目标是它们可以暂停.该包装器仅在WebClient上调用一些areYouFinished方法(例如),如果尚未完成,协程挂起,并且将来将尝试调用同一方法(通过在将来执行时传递未到达的代码).

I think u should use coroutines with WebFlux but not instead of WebFlux. To use WebFlux with coroutines u must add WebFlux-Wrapper which makes WebFlux suspendable. WebFlux+Coroutine example By itself coroutines will not make your code non-blocking, coroutines goal is that they can just suspend. This wrappers just call some areYouFinished method on WebClient (for example), if it's not finished coroutine suspends and it will try to call same method in the future(through passing not reached code in future execution).

这篇关于带有Kotlin协程的Spring Boot休息服务的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆