Currently there are a few ways to initialize beans, but i did not find a way to initialize a class that require a coroutine context.
For example we can take the following class:
class FooService private constructor(...) {
companion object {
suspend fun create(...): FooService {
return FooService(...)
}
}
}
To initialize this service as a bean, it can not be marked as a @Component
and should be registered as a @Bean
. It would be great if the following was possible:
Register @Bean
with a suspend function. e.g.
@Configuration
class FooConfiguration {
@Bean
suspend fun fooService(...) {
return FooService.create(...)
}
}
Add bean using BeanDefinitionDsl
. e.g.
coBeans {
bean {
FooService.create(...)
}
}.initialize(applicationContext)
This also leads to other places where a coroutine context would be helpful, or if the infrastructure would be based on callbacks / futures. For example in my project we have a use-case where we use the beans
dsl to register beans triggered from a ApplicationListener<ContextRefreshedEvent>
. It would be great if onApplicationEvent
could also have a suspend version so the coBeans
dsl could be used from there as well.
Currently the only way i could find to overcome this is using runBlocking
in those places, which is not recommended and can cause problems.
Comment From: sdeleuze
Related to #19487 and #21025.
Comment From: sdeleuze
@tomfi Sorry for the delay, what concrete benefits would you expect compared to using runBlocking
?
Comment From: tomfi
@sdeleuze the main benefit is to avoid using a rather non-safe kotlin coroutine bridge, especially in a non-blocking world where you want to avoid blocking as much as possible in any phase of your code/application.
From the official docs of runBlocking
:
It is designed to bridge regular blocking code to libraries that are written in suspending style, to be used in main functions and in tests.
If it can be avoided, it will be more aligned with non-blocking code and kotlin coroutines as a whole.
Comment From: sdeleuze
I am not sure we should apply suspending/async semantics everywhere. When processing requests, it makes sense. For creating beans, I don't think it makes sense to provide special support for that. Another line of argument is that we don't provide special support for Mono
beans, and Reactive and Coroutines support are almost everywhere in sync. As a consequence, I decline this proposal and advise to use runBlocking
for this use case where we don't provide Reactive/Coroutines support.