{"id":13816318,"url":"https://github.com/konrad-kaminski/spring-kotlin-coroutine","last_synced_at":"2025-05-15T15:32:23.506Z","repository":{"id":41551062,"uuid":"88795239","full_name":"konrad-kaminski/spring-kotlin-coroutine","owner":"konrad-kaminski","description":"Kotlin coroutine support for Spring.","archived":false,"fork":false,"pushed_at":"2021-01-07T16:50:16.000Z","size":371,"stargazers_count":450,"open_issues_count":24,"forks_count":69,"subscribers_count":31,"default_branch":"master","last_synced_at":"2024-11-19T13:37:55.371Z","etag":null,"topics":["coroutine","kotlin","spring"],"latest_commit_sha":null,"homepage":"","language":"Kotlin","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/konrad-kaminski.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-04-19T22:09:10.000Z","updated_at":"2024-11-13T21:01:48.000Z","dependencies_parsed_at":"2022-07-09T07:46:21.346Z","dependency_job_id":null,"html_url":"https://github.com/konrad-kaminski/spring-kotlin-coroutine","commit_stats":null,"previous_names":[],"tags_count":12,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/konrad-kaminski%2Fspring-kotlin-coroutine","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/konrad-kaminski%2Fspring-kotlin-coroutine/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/konrad-kaminski%2Fspring-kotlin-coroutine/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/konrad-kaminski%2Fspring-kotlin-coroutine/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/konrad-kaminski","download_url":"https://codeload.github.com/konrad-kaminski/spring-kotlin-coroutine/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254367644,"owners_count":22059547,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["coroutine","kotlin","spring"],"created_at":"2024-08-04T05:00:38.809Z","updated_at":"2025-05-15T15:32:23.100Z","avatar_url":"https://github.com/konrad-kaminski.png","language":"Kotlin","funding_links":[],"categories":["Kotlin","\u003ca name=\"Kotlin\"\u003e\u003c/a\u003eKotlin"],"sub_categories":[],"readme":"[![Build status](https://travis-ci.org/konrad-kaminski/spring-kotlin-coroutine.svg?branch=master)](https://travis-ci.org/konrad-kaminski/spring-kotlin-coroutine)\n[![Download](https://api.bintray.com/packages/konrad-kaminski/maven/spring-kotlin-coroutine/images/download.svg)](https://bintray.com/konrad-kaminski/maven/spring-kotlin-coroutine/_latestVersion)\n[![Awesome Kotlin Badge](https://kotlin.link/awesome-kotlin.svg)](https://github.com/KotlinBy/awesome-kotlin)\n\n`spring-kotlin-coroutine` is a repository that contains several libraries and a demo app which allows using Kotlin coroutines in \nSpring applications as first-class citizens.\n\n## Project modules\n\nThis project contains several modules:\n1. `spring-kotlin-coroutine` - a library which allow using Kotlin coroutines in Spring applications. It contains support\n   for [`@Coroutine`](#coroutine) annotation, [application events](#application-events), [caching](#cacheable-support),\n   [scheduled tasks](#scheduled-support), [`CoroutineRestOperations`](#coroutinerestoperations), [`DeferredRestOperations`](#deferredrestoperations),\n   [`ListenableFuture` extensions](#listenablefuture-extensions).\n2. `spring-webmvc-kotlin-coroutine` - a library which allow using Kotlin coroutines in Spring MVC applications. It contains\n   support for [web methods](#web-methods).\n3. `spring-webflux-kotlin-coroutine` - a library which allow using Kotlin coroutines in Spring Web Flux applications. It contains\n   support for [Web Flux web methods](#web-flux-web-methods), [`CoroutineWebClient`](#coroutinewebclient) and\n   [functional style routes definition](#functional-style-routes-definition).\n4. `spring-data-mongodb-kotlin-coroutine` - a library which allow using Kotlin coroutines in Spring Data Mongo applications. It contains\n   support for [`CoroutineMongoRepository`](#coroutinemongorepository) and [`CoroutineMongoTemplate`](#coroutinemongotemplate).\n5. `spring-boot-autoconfigure-kotlin-coroutine` - a library which contains autoconfiguration support for `spring-data-mongodb-kotlin-coroutine`\n   via [`@EnableCoroutineMongoRepositories` annotation](#enablecoroutinemongorepositories).  \n6. `spring-kotlin-coroutine-demo` - contains a sample application which demonstrates the use of `spring-kotlin-coroutine` and\n    `spring-webmvc-kotlin-coroutine`.                             \n\n## Supported features\n\nMost of the supported features require adding an [`@EnableCoroutine`](spring-kotlin-coroutine/src/main/kotlin/org/springframework/kotlin/coroutine/EnableCoroutine.kt) annotation to your Spring \n[`@Configuration`](http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/context/annotation/Configuration.html) class.\n\n### @EnableCoroutine\n\nThis annotation enables using the features described below. If it is possible to use a feature without this annotation\nit is explicitly stated so in the feature description. The annotation can be used as follows:\n\n```kotlin\n@Configuration\n@EnableCoroutine(\n    proxyTargetClass = false, mode = AdviceMode.PROXY, \n    order = Ordered.LOWEST_PRECEDENCE, schedulerDispatcher = \"\")\nopen class MyAppConfiguration {\n ...\n}\n```\n\nThe `proxyTargetClass`, `mode` and `order` attributes of [`@EnableCoroutine`](spring-kotlin-coroutine/src/main/kotlin/org/springframework/kotlin/coroutine/EnableCoroutine.kt) follow the same semantics as [`@EnableCaching`](http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/cache/annotation/EnableCaching.html).\n`schedulerDispatcher` is a [`CoroutineDispatcher`](https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines/-coroutine-dispatcher/)\nused to run [`@Scheduled`](http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/scheduling/annotation/Scheduled.html) corroutines.\n\n\u003e Note that currently only [`AdviceMode.PROXY`](http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/context/annotation/AdviceMode.html#PROXY) mode is supported.\n\n### Web methods\n\nBecause coroutines can be suspended and they have an additional implicit callback parameter they cannot be used\nas web methods by default. With special parameter and result handling introduced in `spring-webmvc-kotlin-coroutine`\nyou can safely use coroutines as web methods. You can e.g. have the following component:\n\n```kotlin\n@RestController\nopen class MyController {\n    @GetMapping(\"/customers\")\n    suspend open fun getCustomers(): List\u003cCustomer\u003e {\n       ...\n    }\n}\n```\n\n### @Coroutine\nSpring beans and its methods can be annotated with [`@Coroutine`](spring-kotlin-coroutine/src/main/kotlin/org/springframework/kotlin/coroutine/annotation/Coroutine.kt). Using this annotation you can specify\nthe _coroutine context_ via the `context` attribute and the [_coroutine name_](https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines/-coroutine-name/index.html) via the `name` attribute. \nThe `context` specifies a name of a bean from which a [`CoroutineContext`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.coroutines/-coroutine-context/) can be created. Currently the following\ncontexts/bean types are supported:\n\n1. [`CoroutineContext`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.coroutines/-coroutine-context/) type beans - used directly\n2. `DEFAULT_DISPATCHER` - a constant specifying the [`Dispatchers.Default`](https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines/-dispatchers/-default.html) context\n3. `UNCONFINED` - a constant specifying the [`Dispatchers.Unconfined`](https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines/-dispatchers/-unconfined.html) context\n4. [`Executor`](https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/Executor.html) type beans - converted to [`CoroutineContext`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.coroutines/-coroutine-context/) with [`asCoroutineDispatcher`](https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines/java.util.concurrent.-executor/as-coroutine-dispatcher.html)\n5. Rx2 [`Scheduler`](http://reactivex.io/RxJava/2.x/javadoc/io/reactivex/Scheduler.html) type beans - converted to [`CoroutineContext`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.coroutines/-coroutine-context/) with [`asCoroutineDispatcher`](https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-rx2/kotlinx.coroutines.rx2/io.reactivex.-scheduler/as-coroutine-dispatcher.html)\n6. Reactor [`Scheduler`](https://projectreactor.io/docs/core/release/api/reactor/core/scheduler/Scheduler.html) type beans - converted to [`CoroutineContext`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.coroutines/-coroutine-context/) with [`asCoroutineDispatcher`](https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-reactor/kotlinx.coroutines.reactor/reactor.core.scheduler.-scheduler/as-coroutine-dispatcher.html)\n7. [`TaskScheduler`](http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/scheduling/TaskScheduler.html) type beans - converted to [`CoroutineContext`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.coroutines/-coroutine-context/) with `asCoroutineDispatcher` method of [`TaskSchedulerCoroutineContextResolver`](spring-kotlin-coroutine/src/main/kotlin/org/springframework/kotlin/coroutine/context/resolver/TaskSchedulerCoroutineContextResolver.kt)\n   \nYou can also support your own types of beans or context names by providing Spring beans of type [`CoroutineContextResolver`](spring-kotlin-coroutine/src/main/kotlin/org/springframework/kotlin/coroutine/context/CoroutineContextResolver.kt):\n   \n```kotlin\ninterface CoroutineContextResolver {\n    fun resolveContext(beanName: String, bean: Any?): CoroutineContext?\n}\n```   \n\nUsing [`@Coroutine`](spring-kotlin-coroutine/src/main/kotlin/org/springframework/kotlin/coroutine/annotation/Coroutine.kt) it is quite easy to achieve the same effect as with [`@Async`](http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/scheduling/annotation/Async.html), although the code will look much simpler:\n\n```kotlin\n@RestController\nopen class MyController(\n    private val repository: MyRepository\n) {\n    @GetMapping(\"/customers\")\n    suspend open fun getCustomers(): List\u003cCustomer\u003e {\n       return repository.getAllCustomers()\n    }\n}\n\n@Component\n@Coroutine(DEFAULT_DISPATCHER)\nopen class MyRepository {\n    suspend open fun getAllCustomers(): List\u003cCustomer\u003e {\n      // a blocking code\n      // which will be run with DEFAULT_DISPATCHER context\n      // or simply ForkJoinPool\n      ...\n    }\n}\n```\n\n### Application events\n\nSpring allows you to decouple senders and receivers of application events with the usage of [`ApplicationEventPublisher`](http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/context/ApplicationEventPublisher.html) and\n[`@EventListener`](http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/context/event/EventListener.html) methods. They cannot, however, be coroutines. `spring-kotlin-coroutine` allows you to send\nevents in a way that allows the suspension of event processing. You can also have an [`@EventListener`](http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/context/event/EventListener.html) method which is a\ncoroutine.\n\nFor sending a component with the following interface can be used:\n\n```kotlin\ninterface CoroutineApplicationEventPublisher {\n    suspend fun publishEvent(event: ApplicationEvent)\n\n    suspend fun publishEvent(event: Any)\n}\n```\n\nYour bean can inject this interface or it can implement a [`CoroutineApplicationEventPublisherAware`](spring-kotlin-coroutine/src/main/kotlin/org/springframework/kotlin/coroutine/event/CoroutineApplicationEventPublisherAware.kt) interface and have\nit delivered via a `setCoroutineApplicationEventPublisher` method:\n\n```kotlin\ninterface CoroutineApplicationEventPublisherAware : Aware {\n    fun setCoroutineApplicationEventPublisher(publisher: CoroutineApplicationEventPublisher)\n}\n```\n\nThe events sent by either [`CoroutineApplicationEventPublisher`](spring-kotlin-coroutine/src/main/kotlin/org/springframework/kotlin/coroutine/event/CoroutineApplicationEventPublisher.kt) or [`ApplicationEventPublisher`](http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/context/ApplicationEventPublisher.html) can be received \nby any method annotated with [`@EventListener`](http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/context/event/EventListener.html) (a coroutine or a regular one). The result of coroutine listeners will\nbe handled in the same way as for regular listeners:\n* if it is a [`Unit`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-unit/) nothing will happen\n* if it returns a single value it will be treated as a newly published event\n* if it returns an array or a collection of values it will be treated as a collection of newly published events\n\n### @Cacheable support\n\nDue to an additional callback parameter and a special return value semantics coroutine return values cannot be cached using\ndefault Spring caching feature. However with `spring-kotlin-coroutine` it is possible to use a [`@Cacheable`](http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/cache/annotation/Cacheable.html) annotation \non a coroutine, e.g.:\n\n```kotlin\n@Configuration\n@EnableCaching\n@EnableCoroutine\nopen class MyConfiguration {\n}\n\n@Component\nclass MyComponent {\n    @Cacheable\n    open suspend fun getCustomer(id: String): Customer {\n        ...\n    }\n}\n```\n\n### @Scheduled support\n\nCoroutines annotated with [`@Scheduled`](http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/scheduling/annotation/Scheduled.html) will\nnot work with regular Spring. However, with `spring-kotlin-coroutine` you can use them the same way you would do it with regular methods with the following caveats:\n1. They will be executed using [`CoroutineDispatcher`](https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines/-coroutine-dispatcher/)\n   obtained from:\n   * `schedulerDispatcher` attribute of [`@EnableCoroutine`](spring-kotlin-coroutine/src/main/kotlin/org/springframework/kotlin/coroutine/EnableCoroutine.kt) annotation (if a custom value is specified) - it works the same way as the\n     `context` attribute of [`@Coroutine`](spring-kotlin-coroutine/src/main/kotlin/org/springframework/kotlin/coroutine/annotation/Coroutine.kt) annotation (see [`@Coroutine` section](#coroutine)), or\n   *  [`TaskScheduler`](http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/scheduling/TaskScheduler.html) [used by `ScheduledTaskRegistrar`](http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/scheduling/config/ScheduledTaskRegistrar.html#getScheduler--) from the [`ScheduledAnnotationBeanPostProcessor#registrar`](http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/scheduling/annotation/ScheduledAnnotationBeanPostProcessor.html) \n      converted into [`TaskSchedulerDispatcher`](spring-kotlin-coroutine/src/main/kotlin/org/springframework/kotlin/coroutine/context/resolver/TaskSchedulerCoroutineContextResolver.kt) (which is a [`CoroutineDispatcher`](https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines/-coroutine-dispatcher/) \n      converted with [`TaskSchedulerCoroutineContextResolver`](spring-kotlin-coroutine/src/main/kotlin/org/springframework/kotlin/coroutine/context/resolver/TaskSchedulerCoroutineContextResolver.kt)) - this mimics the default behaviour of Spring for regular [`@Scheduled`](http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/scheduling/annotation/Scheduled.html) \n      annotated method.\n2. The exception thrown from the coroutine will be handled using:\n   * [Default](http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/scheduling/support/TaskUtils.html#getDefaultErrorHandler-boolean-) [`ErrorHandler`](http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/util/ErrorHandler.html) for repeating tasks if [`TaskSchedulerDispatcher`](spring-kotlin-coroutine/src/main/kotlin/org/springframework/kotlin/coroutine/context/resolver/TaskSchedulerCoroutineContextResolver.kt) is used,\n   * [`handleCoroutineException`](https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines/handle-coroutine-exception.html) otherwise.\n\n### CoroutineRestOperations\n\nSpring provides blocking [`RestOperations`](http://docs.spring.io/spring/docs/current/javadoc-api/index.html?org/springframework/web/client/RestOperations.html) to be used as a `REST` client. `spring-kotlin-coroutine` provides \n[`CoroutineRestOperations`](spring-kotlin-coroutine/src/main/kotlin/org/springframework/kotlin/coroutine/web/client/CoroutineRestOperations.kt) interface which has the same methods as [`RestOperations`](http://docs.spring.io/spring/docs/current/javadoc-api/index.html?org/springframework/web/client/RestOperations.html), but as coroutines:\n\n```kotlin\ninterface CoroutineRestOperations {\n    suspend fun \u003cT : Any?\u003e postForObject(url: String, request: Any?, responseType: Class\u003cT\u003e?, vararg uriVariables: Any?): T\n\n    suspend fun \u003cT : Any?\u003e postForObject(url: String, request: Any?, responseType: Class\u003cT\u003e?, uriVariables: Map\u003cString, *\u003e): T\n\n    suspend fun \u003cT : Any?\u003e postForObject(url: URI, request: Any?, responseType: Class\u003cT\u003e?): T\n\n    ...\n}\n```\n\nIn order to create [`CoroutineRestOperations`](spring-kotlin-coroutine/src/main/kotlin/org/springframework/kotlin/coroutine/web/client/CoroutineRestOperations.kt) use the following:\n \n```kotlin\nval restOps = CoroutineRestOperations(restOperations = RestTemplate(), context = null)\nval defaultRestOps = CoroutineRestOperations() \n``` \n\nIf you do not specify any arguments when creating [`CoroutineRestOperations`](spring-kotlin-coroutine/src/main/kotlin/org/springframework/kotlin/coroutine/web/client/CoroutineRestOperations.kt) it will delegate all calls to [`RestTemplate`](http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/web/client/RestTemplate.html)\ninstance and use a special _coroutine context_ which will invoke the blocking method of [`RestTemplate`](http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/web/client/RestTemplate.html) on a separate thread\n (just like [`AsyncRestTemplate`](http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/web/client/AsyncRestTemplate.html)). You can specify your own [`RestOperations`](http://docs.spring.io/spring/docs/current/javadoc-api/index.html?org/springframework/web/client/RestOperations.html) and [`CoroutineContext`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.coroutines.experimental/-coroutine-context/) to change that behaviour.\n\n\u003e Note that [`CoroutineRestOperations`](spring-kotlin-coroutine/src/main/kotlin/org/springframework/kotlin/coroutine/web/client/CoroutineRestOperations.kt) does not need [`@EnableCoroutine`](spring-kotlin-coroutine/src/main/kotlin/org/springframework/kotlin/coroutine/EnableCoroutine.kt) in order to work. Underneath [`CoroutineRestOperations`](spring-kotlin-coroutine/src/main/kotlin/org/springframework/kotlin/coroutine/web/client/CoroutineRestOperations.kt)\nuses [`createCoroutineProxy`](spring-kotlin-coroutine/src/main/kotlin/org/springframework/kotlin/coroutine/proxy/CoroutineProxy.kt).  \n\n### DeferredRestOperations\n\nThe [`kotlinx.coroutines`](https://github.com/Kotlin/kotlinx.coroutines) library provides [`Deferred\u003cT\u003e`](https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.experimental/-deferred/index.html) type \nfor non-blocking cancellable future. Based on that `spring-kotlin-coroutine` provides [`DeferredRestOperations`](spring-kotlin-coroutine/src/main/kotlin/org/springframework/kotlin/coroutine/web/client/DeferredRestOperations.kt) interface which has the same methods as \n[`RestOperations`](http://docs.spring.io/spring/docs/current/javadoc-api/index.html?org/springframework/web/client/RestOperations.html), but with [`Deferred\u003cT\u003e`](https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.experimental/-deferred/index.html) \nreturn type:\n\n```kotlin\ninterface DeferredRestOperations {\n    fun \u003cT : Any?\u003e postForObject(url: String, request: Any?, responseType: Class\u003cT\u003e?, vararg uriVariables: Any?): Deferred\u003cT\u003e\n\n    fun \u003cT : Any?\u003e postForObject(url: String, request: Any?, responseType: Class\u003cT\u003e?, uriVariables: Map\u003cString, *\u003e): Deferred\u003cT\u003e\n\n    fun \u003cT : Any?\u003e postForObject(url: URI, request: Any?, responseType: Class\u003cT\u003e?): Deferred\u003cT\u003e\n\n    ...\n}\n```\n\nIn order to create [`DeferredRestOperations`](spring-kotlin-coroutine/src/main/kotlin/org/springframework/kotlin/coroutine/web/client/DeferredRestOperations.kt) use the following:\n \n```kotlin\nval restOps = DeferredRestOperations(restOperations = RestTemplate(), start = CoroutineStart.DEFAULT, context = COMMON_POOL)\nval defaultRestOps = DeferredRestOperations() \n``` \n\nIf you do not specify any arguments when creating [`DeferredRestOperations`](spring-kotlin-coroutine/src/main/kotlin/org/springframework/kotlin/coroutine/web/client/DeferredRestOperations.kt) it will delegate all calls to [`RestTemplate`](http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/web/client/RestTemplate.html)\ninstance and use a special _coroutine context_ which will immediately invoke the blocking method of [`RestTemplate`](http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/web/client/RestTemplate.html) on a separate thread\n (just like [`AsyncRestTemplate`](http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/web/client/AsyncRestTemplate.html)). You can specify your own [`RestOperations`](http://docs.spring.io/spring/docs/current/javadoc-api/index.html?org/springframework/web/client/RestOperations.html) and [`CoroutineContext`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.coroutines.experimental/-coroutine-context/) to change that behaviour.\nBy changing the `start` parameter value you can specify when the REST operation should be invoked (see [`CoroutineStart`](https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.experimental/-coroutine-start/index.html) for details).\n\n\u003e Note that [`DeferredRestOperations`](spring-kotlin-coroutine/src/main/kotlin/org/springframework/kotlin/coroutine/web/client/DeferredRestOperations.kt) does not need [`@EnableCoroutine`](spring-kotlin-coroutine/src/main/kotlin/org/springframework/kotlin/coroutine/EnableCoroutine.kt) in order to work. Underneath [`DeferredRestOperations`](spring-kotlin-coroutine/src/main/kotlin/org/springframework/kotlin/coroutine/web/client/DeferredRestOperations.kt)\nuses [`createCoroutineProxy`](spring-kotlin-coroutine/src/main/kotlin/org/springframework/kotlin/coroutine/proxy/CoroutineProxy.kt).  \n\n### Web Flux web methods\n\nBy using `spring-webflux-kotlin-coroutine` module instead of `spring-webmvc-kotlin-coroutine` web methods which are\nsuspending functions will use Spring Web Flux. This enables them to use non-blocking I/O API. \n\n### CoroutineWebClient\n\n`CoroutineWebClient` is a counterpart of the Spring Web Flux `WebClient` component. The differences between these components\ncan be found mainly in the functions which operate on reactive types - in `CoroutineWebClient` they are suspending functions\noperating on regular types. Also the naming of the methods can be slightly different (e.g. in `WebClient` you can find `bodyToMono`\nand in `CoroutineWebClient` it is simply `body`).\n\n### Functional style routes definition\n\nTBD\n\n### CoroutineMongoRepository\n\n`spring-data-mongodb-kotlin-coroutine` contains support for `CoroutineMongoRepository`-based repositories. These repositories\nwork as regular Spring Data Mongo or Spring Data Mongo Reactive repositories, but have support for suspending functions\nand `ReceiveChannel` type.\n\n### CoroutineMongoTemplate\n\n`CoroutineMongoTemplate` is a counterpart of regular `MongoTemplate`, but contains suspending functions instead of regular ones.\n\n### EnableCoroutineMongoRepositories\n\nThe `@EnableCoroutineMongoRepositories` annotation works just like `@EnableMongoRepositories` annotation, but enables\nthe usage of `CoroutineMongoRepository` repositories.\n\n### ListenableFuture extensions\n\nThe [`kotlinx.coroutines`](https://github.com/Kotlin/kotlinx.coroutines) library provides interoperability functions with many existing asynchronous libraries (\n[`RxJava v1`](https://github.com/ReactiveX/RxJava/tree/1.x), [`RxJava v2`](https://github.com/ReactiveX/RxJava),\n[`CompletableFuture`](https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/CompletableFuture.html), etc.). However, there is no support for Spring specific [`ListenableFuture`](http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/util/concurrent/ListenableFuture.html) interface. Therefore\n`spring-kotlin-coroutine` provides the following features:\n\n1. `fun \u003cT\u003e listenableFuture(context: CoroutineContext = DefaultDispatcher, block: suspend () -\u003e T): ListenableFuture\u003cT\u003e` - it \n   allows you to create a `ListenableFuture` from a coroutine with specific _coroutine context_. \n2. `fun \u003cT\u003e Deferred\u003cT\u003e.asListenableFuture(): ListenableFuture\u003cT\u003e` - it allows you to create a `ListenableFuture` from\n    Kotlin coroutine specific `Deferred` type.\n3. `suspend fun \u003cT\u003e ListenableFuture\u003cT\u003e.await(): T` - it allows you to create a coroutine from a `ListenableFuture`.    \n\n\u003e Note that these extensions do not need [`@EnableCoroutine`](spring-kotlin-coroutine/src/main/kotlin/org/springframework/kotlin/coroutine/EnableCoroutine.kt) in order to work.\n\n### Utility functions\n\n\u003e Note that utility functions do not need [`@EnableCoroutine`](spring-kotlin-coroutine/src/main/kotlin/org/springframework/kotlin/coroutine/EnableCoroutine.kt) in order to work.\n\n#### createCoroutineProxy\n\n[`createCoroutineProxy`](spring-kotlin-coroutine/src/main/kotlin/org/springframework/kotlin/coroutine/proxy/CoroutineProxy.kt) can be used to create a smart proxy - an instance of an interface which will delegate all\nfunction invocations to a regular object with matching method signatures. The runtime characteristics of this\nproxy call depends on the types of the interface methods, the types of the proxied object methods and\nthe proxy config. The [`createCoroutineProxy`](spring-kotlin-coroutine/src/main/kotlin/org/springframework/kotlin/coroutine/proxy/CoroutineProxy.kt) is declared as follows:\n\n```kotlin\nfun \u003cT: Any\u003e createCoroutineProxy(coroutineInterface: Class\u003cT\u003e, obj: Any, proxyConfig: CoroutineProxyConfig): T\n```\n\nCurrently supported proxy types are as follows:\n\n| Coroutine interface method     | Object method    | Proxy config                   |\n|--------------------------------|------------------|--------------------------------|\n| `suspend fun m(a: A): T`       | `fun m(a: A): T` | `DefaultCoroutineProxyConfig`  |\n| `fun \u003cT\u003e m(a: A): Deferred\u003cT\u003e` | `fun m(a: A): T` | `DeferredCoroutineProxyConfig` |\n\n#### Method.isSuspend\n\n`Method.isSuspend` allows you to check if a method is a coroutine. It is defined as follows:\n\n```kotlin\nval Method.isSuspend: Boolean\n```\n\n## Using in your projects\n\n\u003e Note that this library is experimental and is subject to change.\n\nThe library is published to [konrad-kaminski/maven](https://bintray.com/konrad-kaminski/maven/spring-kotlin-coroutine) Bintray repository.\n\n### Gradle\n\nAdd Bintray repository:\n\n```groovy\nrepositories {\n  maven { url 'https://dl.bintray.com/konrad-kaminski/maven' }\n}\n```\n\nAdd dependencies:\n\n```groovy\ncompile 'org.springframework.kotlin:spring-kotlin-coroutine:0.3.7'\n```\n\n\u003e Note that some of the dependencies of `spring-kotlin-coroutine` are declared as optional. You should declare them as \nruntime dependencies of your application if you want to use the features that require them. The table below contains the \ndetails:\n\u003e\n\u003e | Feature                                                                                                                                | Dependency                                                |\n\u003e |----------------------------------------------------------------------------------------------------------------------------------------|-----------------------------------------------------------|\n\u003e | Web methods                                                                                                                            | `org.springframework:spring-webmvc:5.0.9.RELEASE`         |\n\u003e | Rx2 [`Scheduler`](http://reactivex.io/RxJava/2.x/javadoc/io/reactivex/Scheduler.html) in `@Coroutine`                                  | `org.jetbrains.kotlinx:kotlinx-coroutines-rx2:1.2.1`      |\n\u003e | Reactor [`Scheduler`](https://projectreactor.io/docs/core/release/api/reactor/core/scheduler/Scheduler.html) in `@Coroutine`           | `org.jetbrains.kotlinx:kotlinx-coroutines-reactor:1.2.1`  |\n\nAnd make sure that you use the right Kotlin version:\n\n```groovy\nbuildscript {\n    ext.kotlin_version = '1.3.30'\n}\n```\n\n## FAQ\n\n### Why all the methods/classes have \"Coroutine\" as part of its name and not \"Suspending\"? \n\nIt's a deliberate choice. In most cases _Coroutine_ just sounded better to me and even though sometimes _Suspending_\nmight've been a better choice for consistency _Coroutine_ was used.\n\n## License\n`spring-kotlin-coroutine` is released under version 2.0 of the [Apache License](http://www.apache.org/licenses/LICENSE-2.0).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkonrad-kaminski%2Fspring-kotlin-coroutine","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkonrad-kaminski%2Fspring-kotlin-coroutine","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkonrad-kaminski%2Fspring-kotlin-coroutine/lists"}