diff --git a/build.gradle b/build.gradle index e738f813c0ef59ef04dadbcd42d21ac72e2a1e4f..56c66b2f4c4ed64a615110e84266332c0a8d762e 100644 --- a/build.gradle +++ b/build.gradle @@ -326,7 +326,7 @@ project("spring-build-src") { project("spring-core") { description = "Spring Core" - // Kotlin compiler does not support JDK 9 yet + // Kotlin compiler does not support JDK 9 yet, see https://youtrack.jetbrains.com/issue/KT-14988 if (!JavaVersion.current().java9Compatible) { apply plugin: "kotlin" } @@ -430,7 +430,7 @@ project("spring-core") { project("spring-beans") { description = "Spring Beans" - // Kotlin compiler does not support JDK 9 yet + // Kotlin compiler does not support JDK 9 yet, see https://youtrack.jetbrains.com/issue/KT-14988 if (!JavaVersion.current().java9Compatible) { apply plugin: "kotlin" } @@ -514,6 +514,10 @@ project("spring-context") { description = "Spring Context" apply plugin: "groovy" + // Kotlin compiler does not support JDK 9 yet, see https://youtrack.jetbrains.com/issue/KT-14988 + if (!JavaVersion.current().java9Compatible) { + apply plugin: "kotlin" + } dependencies { compile(project(":spring-aop")) @@ -536,6 +540,7 @@ project("spring-context") { optional("org.aspectj:aspectjweaver:${aspectjVersion}") optional("org.codehaus.groovy:groovy-all:${groovyVersion}") optional("org.beanshell:bsh:2.0b4") + optional("org.jetbrains.kotlin:kotlin-stdlib:${kotlinVersion}") testCompile("org.apache.commons:commons-pool2:2.4.2") testCompile("org.slf4j:slf4j-api:${slf4jVersion}") testCompile("javax.inject:javax.inject-tck:1") @@ -581,7 +586,7 @@ project("spring-oxm") { project("spring-messaging") { description = "Spring Messaging" - // Kotlin compiler does not support JDK 9 yet + // Kotlin compiler does not support JDK 9 yet, see https://youtrack.jetbrains.com/issue/KT-14988 if (!JavaVersion.current().java9Compatible) { apply plugin: "kotlin" } @@ -726,7 +731,7 @@ project("spring-context-indexer") { project("spring-web") { description = "Spring Web" - // Kotlin compiler does not support JDK 9 yet + // Kotlin compiler does not support JDK 9 yet, see https://youtrack.jetbrains.com/issue/KT-14988 if (!JavaVersion.current().java9Compatible) { apply plugin: "kotlin" } @@ -819,7 +824,7 @@ project("spring-web") { project("spring-web-reactive") { description = "Spring Web Reactive" - // Kotlin compiler does not support JDK 9 yet + // Kotlin compiler does not support JDK 9 yet, see https://youtrack.jetbrains.com/issue/KT-14988 if (!JavaVersion.current().java9Compatible) { apply plugin: "kotlin" } diff --git a/spring-beans/src/main/kotlin/org/springframework/beans/factory/BeanFactoryExtension.kt b/spring-beans/src/main/kotlin/org/springframework/beans/factory/BeanFactoryExtension.kt new file mode 100644 index 0000000000000000000000000000000000000000..d9bac3c037f706cd0801d0c74b220341d821c2e0 --- /dev/null +++ b/spring-beans/src/main/kotlin/org/springframework/beans/factory/BeanFactoryExtension.kt @@ -0,0 +1,29 @@ +package org.springframework.beans.factory + +import kotlin.reflect.KClass + +/** + * Extension for [BeanFactory] providing [KClass] based API. + * + * @since 5.0 + */ +object BeanFactoryExtension { + + /** + * @see BeanFactory.getBean(Class) + */ + fun BeanFactory.getBean(requiredType: KClass) = getBean(requiredType.java) + + /** + * @see BeanFactory.getBean(String, Class) + */ + fun BeanFactory.getBean(name: String, requiredType: KClass) = + getBean(name, requiredType.java) + + /** + * @see BeanFactory.getBean(Class, Object...) + */ + fun BeanFactory.getBean(requiredType: KClass, vararg args:Any) = + getBean(requiredType.java, *args) + +} diff --git a/spring-beans/src/main/kotlin/org/springframework/beans/factory/ListableBeanFactoryExtension.kt b/spring-beans/src/main/kotlin/org/springframework/beans/factory/ListableBeanFactoryExtension.kt new file mode 100644 index 0000000000000000000000000000000000000000..ffe70c84c02621ea6c929f38c49f929831503c0c --- /dev/null +++ b/spring-beans/src/main/kotlin/org/springframework/beans/factory/ListableBeanFactoryExtension.kt @@ -0,0 +1,56 @@ +package org.springframework.beans.factory + +import kotlin.reflect.KClass + +/** + * Extension for [ListableBeanFactory] providing [KClass] based API. + * + * @since 5.0 + */ +object ListableBeanFactoryExtension { + + /** + * @see ListableBeanFactory.getBeanNamesForType(Class) + */ + fun ListableBeanFactory.getBeanNamesForType(type: KClass) = + getBeanNamesForType(type.java) + + /** + * @see ListableBeanFactory.getBeanNamesForType(Class, boolean, boolean) + */ + fun ListableBeanFactory.getBeanNamesForType(type: KClass, + includeNonSingletons: Boolean, allowEagerInit: Boolean) = + getBeanNamesForType(type.java, includeNonSingletons, allowEagerInit) + + /** + * @see ListableBeanFactory.getBeansOfType(Class) + */ + fun ListableBeanFactory.getBeansOfType(type: KClass) = + getBeansOfType(type.java) + + /** + * @see ListableBeanFactory.getBeansOfType(Class, boolean, boolean) + */ + fun ListableBeanFactory.getBeansOfType(type: KClass, + includeNonSingletons: Boolean, allowEagerInit: Boolean) = + getBeansOfType(type.java, includeNonSingletons, allowEagerInit) + + /** + * @see ListableBeanFactory.getBeanNamesForAnnotation + */ + fun ListableBeanFactory.getBeanNamesForAnnotation(type: KClass) = + getBeanNamesForAnnotation(type.java) + + /** + * @see ListableBeanFactory.getBeansWithAnnotation + */ + fun ListableBeanFactory.getBeansWithAnnotation(type: KClass) = + getBeansWithAnnotation(type.java) + + /** + * @see ListableBeanFactoryExtension.findAnnotationOnBean + */ + fun ListableBeanFactory.findAnnotationOnBean(beanName:String, type: KClass) = + findAnnotationOnBean(beanName, type.java) + +} 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 new file mode 100644 index 0000000000000000000000000000000000000000..61ca62416581f923e36ac4e5873e2f9c99334b06 --- /dev/null +++ b/spring-context/src/main/kotlin/org/springframework/context/support/GenericApplicationContextExtension.kt @@ -0,0 +1,47 @@ +package org.springframework.context.support + +import org.springframework.beans.factory.config.BeanDefinitionCustomizer +import java.util.function.Supplier +import kotlin.reflect.KClass + +/** + * Extension for [GenericApplicationContext] providing [KClass] based API and + * avoiding specifying a class parameter for the [Supplier] based variant thanks to + * Kotlin reified type parameters. + * + * @since 5.0 + */ +object GenericApplicationContextExtension { + + /** + * @see GenericApplicationContext.registerBean(Class, BeanDefinitionCustomizer...) + */ + fun GenericApplicationContext.registerBean(beanClass: KClass, + vararg customizers: BeanDefinitionCustomizer) { + registerBean(beanClass.java, *customizers) + } + + /** + * @see GenericApplicationContext.registerBean(String, Class, BeanDefinitionCustomizer...) + */ + fun GenericApplicationContext.registerBean(beanName: String, beanClass: KClass, + vararg customizers: BeanDefinitionCustomizer) { + registerBean(beanName, beanClass.java, *customizers) + } + + /** + * @see GenericApplicationContext.registerBean(Class, Supplier, BeanDefinitionCustomizer...) + */ + inline fun GenericApplicationContext.registerBean(supplier: Supplier, + vararg customizers: BeanDefinitionCustomizer) { + registerBean(T::class.java, supplier, *customizers) + } + + /** + * @see GenericApplicationContext.registerBean(String, Class, Supplier, BeanDefinitionCustomizer...) + */ + inline fun GenericApplicationContext.registerBean(name: String, + supplier: Supplier, vararg customizers: BeanDefinitionCustomizer) { + registerBean(name, T::class.java, supplier, *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 new file mode 100644 index 0000000000000000000000000000000000000000..f707d204fd54a6745ba0749c796ed715419ee0c5 --- /dev/null +++ b/spring-context/src/test/kotlin/org/springframework/context/support/GenericApplicationContextExtensionTests.kt @@ -0,0 +1,45 @@ +package org.springframework.context.support + +import org.junit.Assert.assertNotNull +import org.junit.Test +import org.springframework.context.support.GenericApplicationContextExtension.registerBean +import org.springframework.beans.factory.BeanFactoryExtension.getBean +import java.util.function.Supplier + +class GenericApplicationContextExtensionTests { + + @Test + fun registerBeanWithClass() { + val context = GenericApplicationContext() + context.registerBean(BeanA::class) + context.refresh() + assertNotNull(context.getBean(BeanA::class)) + } + + @Test + fun registerBeanWithNameAndClass() { + val context = GenericApplicationContext() + context.registerBean("a", BeanA::class) + context.refresh() + assertNotNull(context.getBean("a")) + } + + @Test + fun registerBeanWithSupplier() { + val context = GenericApplicationContext() + context.registerBean(Supplier { BeanA() }) + context.refresh() + assertNotNull(context.getBean(BeanA::class)) + } + + @Test + fun registerBeanWithNameAndSupplier() { + val context = GenericApplicationContext() + context.registerBean("a", Supplier { BeanA() }) + context.refresh() + assertNotNull(context.getBean("a")) + } + + internal class BeanA + +}