Skip to content

Commit 23497a7

Browse files
committed
Support autowiring by constructor in Kotlin bean DSL
Issue: SPR-16014
1 parent 0e7e95c commit 23497a7

File tree

2 files changed

+51
-10
lines changed

2 files changed

+51
-10
lines changed

spring-context/src/main/kotlin/org/springframework/context/support/BeanDefinitionDsl.kt

Lines changed: 48 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
package org.springframework.context.support
1818

1919
import org.springframework.beans.factory.config.BeanDefinitionCustomizer
20+
import org.springframework.beans.factory.support.AbstractBeanDefinition
2021
import org.springframework.context.ApplicationContextInitializer
2122
import org.springframework.core.env.ConfigurableEnvironment
2223
import java.util.function.Supplier
@@ -29,9 +30,7 @@ import java.util.function.Supplier
2930
* ```
3031
* beans {
3132
* bean<UserHandler>()
32-
* bean {
33-
* Routes(ref(), ref())
34-
* }
33+
* bean<Routes>()
3534
* bean<WebHandler>("webHandler") {
3635
* RouterFunctions.toWebHandler(
3736
* ref<Routes>().router(),
@@ -100,6 +99,35 @@ open class BeanDefinitionDsl(private val condition: (ConfigurableEnvironment) ->
10099
PROTOTYPE
101100
}
102101

102+
/**
103+
* Autowire enum constants.
104+
*/
105+
enum class Autowire {
106+
107+
/**
108+
* Autowire constant that indicates no externally defined autowiring
109+
* @see org.springframework.beans.factory.config.AutowireCapableBeanFactory.AUTOWIRE_NO
110+
*/
111+
NO,
112+
/**
113+
* Autowire constant that indicates autowiring bean properties by name
114+
* @see org.springframework.beans.factory.config.AutowireCapableBeanFactory.AUTOWIRE_BY_NAME
115+
*/
116+
BY_NAME,
117+
/**
118+
* Autowire constant that indicates autowiring bean properties by type
119+
* @see org.springframework.beans.factory.config.AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE
120+
*/
121+
BY_TYPE,
122+
123+
/**
124+
* Autowire constant that indicates autowiring the greediest constructor that can be satisfied
125+
* @see org.springframework.beans.factory.config.AutowireCapableBeanFactory.AUTOWIRE_CONSTRUCTOR
126+
*/
127+
CONSTRUCTOR
128+
129+
}
130+
103131
/**
104132
* Provide read access to some application context facilities.
105133
* @constructor Create a new bean definition context.
@@ -134,6 +162,7 @@ open class BeanDefinitionDsl(private val condition: (ConfigurableEnvironment) ->
134162
* @param scope Override the target scope of this bean, specifying a new scope name.
135163
* @param isLazyInit Set whether this bean should be lazily initialized.
136164
* @param isPrimary Set whether this bean is a primary autowire candidate.
165+
* @param autowireMode Set the autowire mode, `Autowire.CONSTRUCTOR` by default
137166
* @param isAutowireCandidate Set whether this bean is a candidate for getting autowired into some other bean.
138167
* @see GenericApplicationContext.registerBean
139168
* @see org.springframework.beans.factory.config.BeanDefinition
@@ -142,6 +171,7 @@ open class BeanDefinitionDsl(private val condition: (ConfigurableEnvironment) ->
142171
scope: Scope? = null,
143172
isLazyInit: Boolean? = null,
144173
isPrimary: Boolean? = null,
174+
autowireMode: Autowire = Autowire.CONSTRUCTOR,
145175
isAutowireCandidate: Boolean? = null) {
146176

147177
registrations.add {
@@ -150,6 +180,9 @@ open class BeanDefinitionDsl(private val condition: (ConfigurableEnvironment) ->
150180
isLazyInit?.let { bd.isLazyInit = isLazyInit }
151181
isPrimary?.let { bd.isPrimary = isPrimary }
152182
isAutowireCandidate?.let { bd.isAutowireCandidate = isAutowireCandidate }
183+
if (bd is AbstractBeanDefinition) {
184+
bd.autowireMode = autowireMode.ordinal
185+
}
153186
}
154187

155188
when (name) {
@@ -162,12 +195,21 @@ open class BeanDefinitionDsl(private val condition: (ConfigurableEnvironment) ->
162195
/**
163196
* Declare a bean definition using the given supplier for obtaining a new instance.
164197
*
198+
* @param name the name of the bean
199+
* @param scope Override the target scope of this bean, specifying a new scope name.
200+
* @param isLazyInit Set whether this bean should be lazily initialized.
201+
* @param isPrimary Set whether this bean is a primary autowire candidate.
202+
* @param autowireMode Set the autowire mode, `Autowire.NO` by default
203+
* @param isAutowireCandidate Set whether this bean is a candidate for getting autowired into some other bean.
204+
* @param function the bean supplier function
165205
* @see GenericApplicationContext.registerBean
206+
* @see org.springframework.beans.factory.config.BeanDefinition
166207
*/
167208
inline fun <reified T : Any> bean(name: String? = null,
168209
scope: Scope? = null,
169210
isLazyInit: Boolean? = null,
170211
isPrimary: Boolean? = null,
212+
autowireMode: Autowire = Autowire.NO,
171213
isAutowireCandidate: Boolean? = null,
172214
crossinline function: BeanDefinitionContext.() -> T) {
173215

@@ -176,6 +218,9 @@ open class BeanDefinitionDsl(private val condition: (ConfigurableEnvironment) ->
176218
isLazyInit?.let { bd.isLazyInit = isLazyInit }
177219
isPrimary?.let { bd.isPrimary = isPrimary }
178220
isAutowireCandidate?.let { bd.isAutowireCandidate = isAutowireCandidate }
221+
if (bd is AbstractBeanDefinition) {
222+
bd.autowireMode = autowireMode.ordinal
223+
}
179224
}
180225

181226
registrations.add {

src/docs/asciidoc/kotlin.adoc

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -192,9 +192,7 @@ how beans are registered.
192192
----
193193
fun beans() = beans {
194194
bean<UserHandler>()
195-
bean {
196-
Routes(ref(), ref())
197-
}
195+
bean<Routes>()
198196
bean<WebHandler>("webHandler") {
199197
RouterFunctions.toWebHandler(
200198
ref<Routes>().router(),
@@ -222,9 +220,7 @@ fun beans() = beans {
222220
}
223221
----
224222

225-
In this example, `Routes(ref(), ref())` is the equivalent of `Routes(ref<UserHandler>(), ref<MessageSource>())`
226-
(types are not required thanks to Kotlin type inference) where `ref<UserHandler>()`
227-
is a shortcut for `applicationContext.getBean(UserHandler::class.java)`.
223+
In this example, `ref<Routes>()` is a shortcut for `applicationContext.getBean(Routes::class.java)`.
228224

229225
This `beans()` function can then be used to register beans on the application context.
230226

@@ -242,7 +238,7 @@ This DSL is programmatic, thus it allows custom registration logic of beans
242238
via an `if` expression, a `for` loop or any other Kotlin constructs.
243239
====
244240

245-
See https://github.com/sdeleuze/spring-kotlin-functional/blob/3d12ab102c28f4761bd6a0736e2f585713eb2243/src/main/kotlin/functional/Beans.kt[spring-kotlin-functional beans declaration]
241+
See https://github.com/sdeleuze/spring-kotlin-functional/blob/master/src/main/kotlin/functional/Beans.kt[spring-kotlin-functional beans declaration]
246242
for a concrete example.
247243

248244
[NOTE]

0 commit comments

Comments
 (0)