Coroutines
Kotlin Coroutines 是轻量级线程,允许强制性地编写非阻塞代码。在语言方面,suspend
函数为异步操作提供了一个抽象,而 kotlinx.coroutines 在库方面提供了 async { }
等函数和 Flow
等类型。
Kotlin Coroutines are lightweight threads allowing to write non-blocking code imperatively.
On language side, suspend
functions provides an abstraction for asynchronous operations while on library side kotlinx.coroutines provides functions like async { }
and types like Flow
.
Spring Data 模块为以下范围内的协程提供支持:
Spring Data modules provide support for Coroutines on the following scope:
Dependencies
当 kotlinx-coroutines-core
、kotlinx-coroutines-reactive
和 kotlinx-coroutines-reactor
依赖项在 classpath 中时,协程支持处于启用状态:
Coroutines support is enabled when kotlinx-coroutines-core
, kotlinx-coroutines-reactive
and kotlinx-coroutines-reactor
dependencies are in the classpath:
<dependency>
<groupId>org.jetbrains.kotlinx</groupId>
<artifactId>kotlinx-coroutines-core</artifactId>
</dependency>
<dependency>
<groupId>org.jetbrains.kotlinx</groupId>
<artifactId>kotlinx-coroutines-reactive</artifactId>
</dependency>
<dependency>
<groupId>org.jetbrains.kotlinx</groupId>
<artifactId>kotlinx-coroutines-reactor</artifactId>
</dependency>
支持版本 |
Supported versions |
How Reactive translates to Coroutines?
对于返回值,从 Reactive 到协程 API 的转换如下所示:
For return values, the translation from Reactive to Coroutines APIs is the following:
-
fun handler(): Mono<Void>
becomessuspend fun handler()
-
fun handler(): Mono<T>
becomessuspend fun handler(): T
orsuspend fun handler(): T?
depending on if theMono
can be empty or not (with the advantage of being more statically typed) -
fun handler(): Flux<T>
becomesfun handler(): Flow<T>
Flow
是 Coroutines 世界中 Flux
的等价物,适用于热流或冷流、有限流或无限流,具有以下主要区别:
Flow
is Flux
equivalent in Coroutines world, suitable for hot or cold stream, finite or infinite streams, with the following main differences:
-
Flow
is push-based whileFlux
is push-pull hybrid -
Backpressure is implemented via suspending functions
-
Flow
has only a single suspendingcollect
method and operators are implemented as extensions -
Operators are easy to implement thanks to Coroutines
-
Extensions allow adding custom operators to
Flow
-
Collect operations are suspending functions
-
map
operator supports asynchronous operation (no need forflatMap
) since it takes a suspending function parameter
阅读有关 Going Reactive with Spring, Coroutines and Kotlin Flow 的博客文章以获得更多详细信息,包括如何使用 Coroutines 并发运行代码。
Read this blog post about Going Reactive with Spring, Coroutines and Kotlin Flow for more details, including how to run code concurrently with Coroutines.
Repositories
以下是协程存储库的一个示例:
Here is an example of a Coroutines repository:
interface CoroutineRepository : CoroutineCrudRepository<User, String> {
suspend fun findOne(id: String): User
fun findByFirstname(firstname: String): Flow<User>
suspend fun findAllByFirstname(id: String): List<User>
}
协程存储库建立在响应式存储库上,以通过 Kotlin 的协程公开非阻塞数据访问本质。协程存储库上的方法可以由查询方法或自定义实现支持。如果自定义方法为 suspend
,调用自定义实现方法会将协程调用传播到实际实现方法,而不要求实现方法返回响应式类型,如 Mono
或 Flux
。
Coroutines repositories are built on reactive repositories to expose the non-blocking nature of data access through Kotlin’s Coroutines.
Methods on a Coroutines repository can be backed either by a query method or a custom implementation.
Invoking a custom implementation method propagates the Coroutines invocation to the actual implementation method if the custom method is suspend
-able without requiring the implementation method to return a reactive type such as Mono
or Flux
.
请注意,根据方法声明,协程上下文可能可用或不可用。要保留对上下文的访问,请使用 suspend
声明你的方法或返回能启用上下文传播的类型,如 Flow
。
Note that depending on the method declaration the coroutine context may or may not be available.
To retain access to the context, either declare your method using suspend
or return a type that enables context propagation such as Flow
.
-
suspend fun findOne(id: String): User
: Retrieve the data once and synchronously by suspending. -
fun findByFirstname(firstname: String): Flow<User>
: Retrieve a stream of data. TheFlow
is created eagerly while data is fetched uponFlow
interaction (Flow.collect(…)
). -
fun getUser(): User
: Retrieve data once blocking the thread and without context propagation. This should be avoided.
只有当存储库扩展 |
Coroutines repositories are only discovered when the repository extends the |