コルーチン

Kotlin コルーチン (英語) は、ノンブロッキングコードを命令的に記述することを可能にする軽量スレッドです。言語側では、suspend 関数は非同期操作の抽象化を提供し、ライブラリ側では kotlinx.coroutines [GitHub] (英語) async { } (英語) などの関数と Flow (英語) などの型を提供します。

Spring Data モジュールは、次のスコープでコルーチンのサポートを提供します。

依存関係

コルーチンのサポートは、kotlinx-coroutines-corekotlinx-coroutines-reactivekotlinx-coroutines-reactor の依存関係がクラスパスにある場合に有効になります。

Maven pom.xml に追加する依存関係
<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>
サポートされているバージョン 1.3.0 以上。

Reactive はコルーチンにどのように変換されますか?

戻り値の場合、Reactive API から Coroutines API への変換は次のとおりです。

  • fun handler(): Mono<Void> は suspend fun handler() になります

  • fun handler(): Mono<T> は、Mono を空にできるかどうかに応じて、suspend fun handler(): T または suspend fun handler(): T? になります。(より静的に型付けされるという利点がある)

  • fun handler(): Flux<T> は fun handler(): Flow<T> になります

Flow (英語) は、コルーチンの世界で Flux に相当し、ホットストリームまたはコールドストリーム、有限ストリームまたは無限ストリームに適していますが、主な違いは次のとおりです。

コルーチンと並行してコードを実行する方法など、詳細については、Spring、コルーチン、Kotlin フローで反応する (英語) に関するこのブログ投稿を参照してください。

リポジトリ

コルーチンリポジトリの例を次に示します。

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 -able の場合、実装メソッドが Mono や Flux などのリアクティブ型を返す必要はありません。

メソッド宣言に応じて、コルーチンコンテキストが使用できる場合とできない場合があることに注意してください。コンテキストへのアクセスを保持するには、suspend を使用してメソッドを宣言するか、Flow などのコンテキスト伝播を有効にする型を返します。

  • suspend fun findOne(id: String): User: 一時停止して、データを 1 回だけ同期的に取得します。

  • fun findByFirstname(firstname: String): Flow<User>: データのストリームを取得します。Flow は、Flow の相互作用(Flow.collect(…))でデータがフェッチされている間、先行して作成されます。

  • fun getUser(): User: スレッドをブロックした後、コンテキスト伝播なしでデータを取得します。これは避けるべきです。

コルーチンリポジトリは、リポジトリが CoroutineCrudRepository インターフェースを継承する場合にのみ検出されます。