From c5cfd8c8fc6b76b875a1544b82e10e5d64dc8e0e Mon Sep 17 00:00:00 2001 From: Sebastien Deleuze Date: Tue, 10 Jan 2017 10:13:26 +0100 Subject: [PATCH] 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 --- .../GenericApplicationContextExtension.kt | 8 +++--- ...GenericApplicationContextExtensionTests.kt | 26 +++++++++++++++++-- 2 files changed, 28 insertions(+), 6 deletions(-) diff --git a/spring-context/src/main/kotlin/org/springframework/context/support/GenericApplicationContextExtension.kt b/spring-context/src/main/kotlin/org/springframework/context/support/GenericApplicationContextExtension.kt index 7e57d99c0be..55474ed4b18 100644 --- a/spring-context/src/main/kotlin/org/springframework/context/support/GenericApplicationContextExtension.kt +++ b/spring-context/src/main/kotlin/org/springframework/context/support/GenericApplicationContextExtension.kt @@ -34,15 +34,15 @@ object GenericApplicationContextExtension { * @see GenericApplicationContext.registerBean(Class, Supplier, BeanDefinitionCustomizer...) */ inline fun GenericApplicationContext.registerBean( - crossinline supplier: () -> T, vararg customizers: BeanDefinitionCustomizer) { - registerBean(T::class.java, Supplier { supplier.invoke() }, *customizers) + vararg customizers: BeanDefinitionCustomizer, crossinline function: (GenericApplicationContext) -> T) { + registerBean(T::class.java, Supplier { function.invoke(this) }, *customizers) } /** * @see GenericApplicationContext.registerBean(String, Class, Supplier, BeanDefinitionCustomizer...) */ inline fun GenericApplicationContext.registerBean(name: String, - crossinline supplier: () -> T, vararg customizers: BeanDefinitionCustomizer) { - registerBean(name, T::class.java, Supplier { supplier.invoke() }, *customizers) + vararg customizers: BeanDefinitionCustomizer, crossinline function: (GenericApplicationContext) -> T) { + registerBean(name, T::class.java, Supplier { function.invoke(this) }, *customizers) } } diff --git a/spring-context/src/test/kotlin/org/springframework/context/support/GenericApplicationContextExtensionTests.kt b/spring-context/src/test/kotlin/org/springframework/context/support/GenericApplicationContextExtensionTests.kt index 4b4a4c5d574..daaa8873cfb 100644 --- a/spring-context/src/test/kotlin/org/springframework/context/support/GenericApplicationContextExtensionTests.kt +++ b/spring-context/src/test/kotlin/org/springframework/context/support/GenericApplicationContextExtensionTests.kt @@ -26,7 +26,7 @@ class GenericApplicationContextExtensionTests { @Test fun registerBeanWithSupplier() { val context = GenericApplicationContext() - context.registerBean({ BeanA() }) + context.registerBean { BeanA() } context.refresh() assertNotNull(context.getBean(BeanA::class)) } @@ -34,11 +34,33 @@ class GenericApplicationContextExtensionTests { @Test fun registerBeanWithNameAndSupplier() { val context = GenericApplicationContext() - context.registerBean("a", { BeanA() }) + context.registerBean("a") { BeanA() } context.refresh() 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 BeanB(val a: BeanA) + }