Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/kotlin/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Spring boot 与Kotlin合作的Spring Boot Rest服务_Spring Boot_Kotlin_Kotlin Coroutines - Fatal编程技术网

Spring boot 与Kotlin合作的Spring Boot Rest服务

Spring boot 与Kotlin合作的Spring Boot Rest服务,spring-boot,kotlin,kotlin-coroutines,Spring Boot,Kotlin,Kotlin Coroutines,我正在Kotlin编写一个Spring Boot Rest服务。我想使用协同路由作为Webflux的替代方案,以实现非阻塞异步行为。我使用的是Spring Boot 2.1,我知道我无法实现真正的非阻塞行为,因为我在控制器上阻塞。然而,直到SpringBoot2.2正式面世之前,我都同意这一点 我的应用程序是三层的ie控制器->服务->存储库。在存储库中,我正在调用其他服务(即网络调用),并将该方法标记为suspend 我想确保这是否是正确的方法,此外,调用ResourceService是否会阻

我正在Kotlin编写一个Spring Boot Rest服务。我想使用协同路由作为Webflux的替代方案,以实现非阻塞异步行为。我使用的是Spring Boot 2.1,我知道我无法实现真正的非阻塞行为,因为我在
控制器上阻塞。然而,直到SpringBoot2.2正式面世之前,我都同意这一点

我的应用程序是三层的ie控制器->服务->存储库。在存储库中,我正在调用其他服务(即网络调用),并将该方法标记为suspend

我想确保这是否是正确的方法,此外,调用
ResourceService
是否会阻止调用线程

同样,在阅读了Roman Elizarov的文章之后,我不确定是否应该将
与上下文一起使用
,以及所有挂起函数

打包my.springbootapp
导入kotlinx.coroutines.Dispatchers
导入kotlinx.coroutines.asCoroutineDispatcher
导入kotlinx.coroutines.runBlocking
导入kotlinx.coroutines.withContext
导入mu.KotlinLogging
导入org.springframework.boot.SpringApplication
导入org.springframework.boot.autoconfigure.springboot应用程序
导入org.springframework.stereotype.Repository
导入org.springframework.stereotype.Service
导入org.springframework.web.bind.annotation.GetMapping
导入org.springframework.web.bind.annotation.PathVariable
导入org.springframework.web.bind.annotation.RestController
导入java.util.concurrent.Executors
val logger=KotlinLogging.logger{}
@SpringBoot应用程序
类应用程序
趣味主线(args:Array){
run(App::class.java,*args)
}
@RestController
类控制器(专用val resourceService:resourceService){
private val dispatcher=Executors.newFixedThreadPool(5).ascoroutineddispatcher()
@GetMapping(“/resource/{id}”)
fun getResource(@PathVariable(“id”)id:String)=运行阻塞(调度程序){
resourceService.get(id).还有{logger.info{Thread.currentThread().name+“Returning$it”}
}
}
@服务
类ResourceService(专用val networkResourceRepository:networkResourceRepository){
suspend-fun-get(id:String):资源{
logger.info{Thread.currentThread().name+“获取资源”}
返回networkResourceRepository.get(id)
}
}
@存储库
类NetworkResourceRepository{
suspend-fun-get(id:String):Resource=withContext(Dispatchers.IO){
logger.info{Thread.currentThread().name+“正在从n/w获取资源”}
//IO操作
资源(“资源数据”)
}
}
数据类资源(val数据:字符串)

您是否查看了上的新文档

您感兴趣的是带有@Controller的类支持以下内容:

  • Spring WebFlux中支持延迟和流返回值
  • SpringWebFlux中的暂停功能支持
所以我想你可以用暂停

@RestController
class Controller(private val resourceService: ResourceService) {

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

我认为你应该使用与WebFlux的协同程序,但不能代替WebFlux。要将WebFlux与协同程序一起使用,必须添加WebFlux包装器,使WebFlux可挂起。
协同路由本身不会使代码无阻塞,协同路由的目标是它们可以挂起。此包装器只需在
WebClient
上调用一些
areYouFinished
方法(例如),如果尚未完成,则会挂起协同路由,并在将来尝试调用相同的方法(通过在将来的执行中传递未到达的代码)

“不过,到SpringBoot2.2正式发布之前,我对这一点还没有意见。”——>SpringBoot2.2是上周发布的,所以试试吧。这是一种更好的体验。从端点删除
runBlocking
。SpringBoot中的每个请求都在单独的线程中处理。您的
ResourceService
不应公开挂起的函数。在内部创建协同路由,但向外部隐藏它们。我在创建bean时遇到错误:
创建名为'requestMappingHandlerMapping'的bean时出错,该bean在类路径资源[org/springframework/boot/autoconfigure/web/servlet/WebMvcAutoConfiguration$enablewbmvcconfiguration.class]中定义:init方法调用失败;嵌套的异常是java.lang.IllegalStateException:检测到不支持的挂起处理程序方法
也许您知道如何克服这个问题吗?