This commit review the support for AOT by only ignoring beans that are
using an instance supplier. The Kotlin DSL has a way to register a
bean by type where all inferences should happen as usual and that was
previously ignored.
This commit no longer ignores those beans so AOT can optimize them, and
makes sure that they are not registered again when running with AOT
optimizations. This change makes it so that the order in which beans are
registered is now different when running with AOT optimizations, and
we'll have to find a solution for that.
See gh-29555
This commit adds AOT/Native support for beans that are contributed by
the Kotlin DSL.
Since they use an instance supplier, such beans are now configured to
be ignored by AOT generation. They are part of the bean factory still
so any hint generation works.
This commit removes a previous attempt at fixing this issue when we
were not checking for instance suppliers. Rather than skipping the
initializr at runtime, it runs again as intended since their state
can't be stored in AOT-generated code.
Closes gh-29555
Before this commit, beans registered with the Kotlin bean DSL
typically added via SpringApplication#addInitializers
were registered 2 times: by the code generated AOT and by
the listener executed at runtime.
After this commit, such beans are only registered 1 time when
AOT generation is involved, and does not require specific
reflection hints on native execution anymore.
Closes gh-29211
This commit updates Kotlin beans DSL in order to support
creating beans using callable references with autowired
parameters. Type resolution is implemented using Kotlin
reified type parameters without requiring reflection.
Closes gh-21845
Spring Framework 5.1.0 exposed by mistake context in the Kotlin bean DSL
API in order to fix SPR-16269. Now that BeanFactory#getBeanprovider is
available, it should be exposed via a provider<Foo>() function in order
to provide a more clean API instead.
Issue: SPR-17352
Since non-default constructors are now evaluated for autowiring,
there is no need anymore for setting autowiring mode or exposing
it in Kotlin bean DSL.
Issue: SPR-17292
This commit introduces a deferred initialization of the declared beans
in order to make it possible to access to the environment (and even
to the context for advanced use-cases) in the beans { } Kotlin DSL.
Issues: SPR-16269, SPR-16412
By using function literals with receiver, we can avoid requiring
lambda parameters for a shorter and nicer syntax. Based on a
proposal from Joseph Taylor.
Issue: SPR-15815
As a follow-up of the ApplicationContext Kotlin extensions, close to
the Kotlin functional WebFlux DSL and partially inspired of the
Groovy/Scala bean configuration DSL, this commit introduces a
lightweight Kotlin DSL for functional bean declaration.
It allows declaring beans as following:
beans {
bean<Foo>()
profile("bar") {
bean<Bar>("bar", scope = Scope.PROTOTYPE)
}
environment({ it.activeProfiles.contains("baz") }) {
bean { Baz(it.ref()) }
bean { Baz(it.ref("bar")) }
}
}
Advantages compared to Regular ApplicationContext API are:
- No exposure of low-level ApplicationContext API
- Focused DSL easier to read, but also easier to write with a fewer
entries in the auto-complete
- Declarative syntax instead of functions with verbs like registerBeans
while still allowing programmatic registration of beans if needed
- Such DSL is idiomatic in Kotlin
- No need to have an ApplicationContext instance to write how you
register your beans since beans { } DSL is conceptually a
Consumer<GenericApplicationContext>
This DSL effectively replaces ApplicationContext Kotlin extensions as
the recommended way to register beans in a functional way with Kotlin.
Issue: SPR-15755
Put the lambda parameter at the end and use a function
instead of a supplier to be able to register beans like this:
val context = GenericApplicationContext()
context.registerBean(Foo::class)
context.registerBean{ Bar(it.getBean(Foo::class)) }
Issue: SPR-15118
Based on an idea from Mario Arias, we can avoid requiring specifying
explicitly Supplier lambda type in Kotlin API by declaring the supplier
parameter as "crossinline supplier: () -> T" instead of
"supplier: Supplier<T>".
Issue: SPR-15118