Make the Kotlin bean registration API even more idiomatic

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
This commit is contained in:
Sebastien Deleuze
2017-01-10 10:13:26 +01:00
parent 715274e327
commit c5cfd8c8fc
2 changed files with 28 additions and 6 deletions

View File

@@ -34,15 +34,15 @@ object GenericApplicationContextExtension {
* @see GenericApplicationContext.registerBean(Class<T>, Supplier<T>, BeanDefinitionCustomizer...) * @see GenericApplicationContext.registerBean(Class<T>, Supplier<T>, BeanDefinitionCustomizer...)
*/ */
inline fun <reified T : Any> GenericApplicationContext.registerBean( inline fun <reified T : Any> GenericApplicationContext.registerBean(
crossinline supplier: () -> T, vararg customizers: BeanDefinitionCustomizer) { vararg customizers: BeanDefinitionCustomizer, crossinline function: (GenericApplicationContext) -> T) {
registerBean(T::class.java, Supplier { supplier.invoke() }, *customizers) registerBean(T::class.java, Supplier { function.invoke(this) }, *customizers)
} }
/** /**
* @see GenericApplicationContext.registerBean(String, Class<T>, Supplier<T>, BeanDefinitionCustomizer...) * @see GenericApplicationContext.registerBean(String, Class<T>, Supplier<T>, BeanDefinitionCustomizer...)
*/ */
inline fun <reified T : Any> GenericApplicationContext.registerBean(name: String, inline fun <reified T : Any> GenericApplicationContext.registerBean(name: String,
crossinline supplier: () -> T, vararg customizers: BeanDefinitionCustomizer) { vararg customizers: BeanDefinitionCustomizer, crossinline function: (GenericApplicationContext) -> T) {
registerBean(name, T::class.java, Supplier { supplier.invoke() }, *customizers) registerBean(name, T::class.java, Supplier { function.invoke(this) }, *customizers)
} }
} }

View File

@@ -26,7 +26,7 @@ class GenericApplicationContextExtensionTests {
@Test @Test
fun registerBeanWithSupplier() { fun registerBeanWithSupplier() {
val context = GenericApplicationContext() val context = GenericApplicationContext()
context.registerBean({ BeanA() }) context.registerBean { BeanA() }
context.refresh() context.refresh()
assertNotNull(context.getBean(BeanA::class)) assertNotNull(context.getBean(BeanA::class))
} }
@@ -34,11 +34,33 @@ class GenericApplicationContextExtensionTests {
@Test @Test
fun registerBeanWithNameAndSupplier() { fun registerBeanWithNameAndSupplier() {
val context = GenericApplicationContext() val context = GenericApplicationContext()
context.registerBean("a", { BeanA() }) context.registerBean("a") { BeanA() }
context.refresh() context.refresh()
assertNotNull(context.getBean("a")) assertNotNull(context.getBean("a"))
} }
@Test
fun registerBeanWithFunction() {
val context = GenericApplicationContext()
context.registerBean(BeanA::class)
context.registerBean { BeanB(it.getBean(BeanA::class)) }
context.refresh()
assertNotNull(context.getBean(BeanA::class))
assertNotNull(context.getBean(BeanB::class))
}
@Test
fun registerBeanWithNameAndFunction() {
val context = GenericApplicationContext()
context.registerBean("a", BeanA::class)
context.registerBean("b") { BeanB(it.getBean(BeanA::class)) }
context.refresh()
assertNotNull(context.getBean("a"))
assertNotNull(context.getBean("b"))
}
internal class BeanA internal class BeanA
internal class BeanB(val a: BeanA)
} }