I have a Micronaut controller that takes the java.time.Clock
as a dependency:
@Controller("/foo")
class FooListener (
private val clock: Clock,
) {
// ...
}
IntelliJ warns:
Unsatisfied dependency: no bean matches the injection point
Inspection info: Reports injection points in bean classes that have missing or ambiguous dependencies.
and the application does not start:
Error starting Micronaut server: Bean definition [FooListener] could not be loaded: Failed to inject value for parameter [clock] of class: FooListener
Message: No bean of type [java.time.Clock] exists.
I've tried a @PostConstruct
in the main application instance:
object Application {
@JvmStatic
fun main(args: Array<String>) {
Micronaut.build()
.eagerInitSingletons(true)
.eagerInitConfiguration(true)
.mainClass(Application.javaClass)
.start()
}
@PostConstruct
fun onStart(context: ApplicationContext) {
context.registerSingleton(Clock::class.java, Clock.systemUTC())
}
}
but that seemed to get ignored; maybe code in main
runs first and the problem happens before the @PostConstruct
runs.
Adding this little wrapper class did not help either:
class ClockConfig {
@Bean
fun clock(): Clock = Clock.systemUTC()
}
When I add @io.micronaut.context.annotation.Configuration
to that ClockConfig
class, the compiler complains that "This annotation is not applicable to target 'class'", and it looks like it applies to packages.
How can I put a Clock in the application context with Clock.systemUTC()
as the value?
Seems like a Factory does the trick:
import io.micronaut.context.annotation.Factory
import jakarta.inject.Singleton
import java.time.Clock
@Factory
class ClockFactory {
@Singleton
fun clock(): Clock = Clock.systemUTC()
}