Skip to content

Commit ff675f5

Browse files
committed
Add Kotlin extensions for bean registration and retrieval
Issue: SPR-15048
1 parent a8741dd commit ff675f5

File tree

5 files changed

+187
-5
lines changed

5 files changed

+187
-5
lines changed

build.gradle

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -326,7 +326,7 @@ project("spring-build-src") {
326326
project("spring-core") {
327327
description = "Spring Core"
328328

329-
// Kotlin compiler does not support JDK 9 yet
329+
// Kotlin compiler does not support JDK 9 yet, see https://youtrack.jetbrains.com/issue/KT-14988
330330
if (!JavaVersion.current().java9Compatible) {
331331
apply plugin: "kotlin"
332332
}
@@ -430,7 +430,7 @@ project("spring-core") {
430430
project("spring-beans") {
431431
description = "Spring Beans"
432432

433-
// Kotlin compiler does not support JDK 9 yet
433+
// Kotlin compiler does not support JDK 9 yet, see https://youtrack.jetbrains.com/issue/KT-14988
434434
if (!JavaVersion.current().java9Compatible) {
435435
apply plugin: "kotlin"
436436
}
@@ -514,6 +514,10 @@ project("spring-context") {
514514
description = "Spring Context"
515515

516516
apply plugin: "groovy"
517+
// Kotlin compiler does not support JDK 9 yet, see https://youtrack.jetbrains.com/issue/KT-14988
518+
if (!JavaVersion.current().java9Compatible) {
519+
apply plugin: "kotlin"
520+
}
517521

518522
dependencies {
519523
compile(project(":spring-aop"))
@@ -536,6 +540,7 @@ project("spring-context") {
536540
optional("org.aspectj:aspectjweaver:${aspectjVersion}")
537541
optional("org.codehaus.groovy:groovy-all:${groovyVersion}")
538542
optional("org.beanshell:bsh:2.0b4")
543+
optional("org.jetbrains.kotlin:kotlin-stdlib:${kotlinVersion}")
539544
testCompile("org.apache.commons:commons-pool2:2.4.2")
540545
testCompile("org.slf4j:slf4j-api:${slf4jVersion}")
541546
testCompile("javax.inject:javax.inject-tck:1")
@@ -581,7 +586,7 @@ project("spring-oxm") {
581586
project("spring-messaging") {
582587
description = "Spring Messaging"
583588

584-
// Kotlin compiler does not support JDK 9 yet
589+
// Kotlin compiler does not support JDK 9 yet, see https://youtrack.jetbrains.com/issue/KT-14988
585590
if (!JavaVersion.current().java9Compatible) {
586591
apply plugin: "kotlin"
587592
}
@@ -726,7 +731,7 @@ project("spring-context-indexer") {
726731
project("spring-web") {
727732
description = "Spring Web"
728733

729-
// Kotlin compiler does not support JDK 9 yet
734+
// Kotlin compiler does not support JDK 9 yet, see https://youtrack.jetbrains.com/issue/KT-14988
730735
if (!JavaVersion.current().java9Compatible) {
731736
apply plugin: "kotlin"
732737
}
@@ -819,7 +824,7 @@ project("spring-web") {
819824
project("spring-web-reactive") {
820825
description = "Spring Web Reactive"
821826

822-
// Kotlin compiler does not support JDK 9 yet
827+
// Kotlin compiler does not support JDK 9 yet, see https://youtrack.jetbrains.com/issue/KT-14988
823828
if (!JavaVersion.current().java9Compatible) {
824829
apply plugin: "kotlin"
825830
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
package org.springframework.beans.factory
2+
3+
import kotlin.reflect.KClass
4+
5+
/**
6+
* Extension for [BeanFactory] providing [KClass] based API.
7+
*
8+
* @since 5.0
9+
*/
10+
object BeanFactoryExtension {
11+
12+
/**
13+
* @see BeanFactory.getBean(Class<T>)
14+
*/
15+
fun <T : Any> BeanFactory.getBean(requiredType: KClass<T>) = getBean(requiredType.java)
16+
17+
/**
18+
* @see BeanFactory.getBean(String, Class<T>)
19+
*/
20+
fun <T : Any> BeanFactory.getBean(name: String, requiredType: KClass<T>) =
21+
getBean(name, requiredType.java)
22+
23+
/**
24+
* @see BeanFactory.getBean(Class<T>, Object...)
25+
*/
26+
fun <T : Any> BeanFactory.getBean(requiredType: KClass<T>, vararg args:Any) =
27+
getBean(requiredType.java, *args)
28+
29+
}
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
package org.springframework.beans.factory
2+
3+
import kotlin.reflect.KClass
4+
5+
/**
6+
* Extension for [ListableBeanFactory] providing [KClass] based API.
7+
*
8+
* @since 5.0
9+
*/
10+
object ListableBeanFactoryExtension {
11+
12+
/**
13+
* @see ListableBeanFactory.getBeanNamesForType(Class<?>)
14+
*/
15+
fun <T : Any> ListableBeanFactory.getBeanNamesForType(type: KClass<T>) =
16+
getBeanNamesForType(type.java)
17+
18+
/**
19+
* @see ListableBeanFactory.getBeanNamesForType(Class<?>, boolean, boolean)
20+
*/
21+
fun <T : Any> ListableBeanFactory.getBeanNamesForType(type: KClass<T>,
22+
includeNonSingletons: Boolean, allowEagerInit: Boolean) =
23+
getBeanNamesForType(type.java, includeNonSingletons, allowEagerInit)
24+
25+
/**
26+
* @see ListableBeanFactory.getBeansOfType(Class<T>)
27+
*/
28+
fun <T : Any> ListableBeanFactory.getBeansOfType(type: KClass<T>) =
29+
getBeansOfType(type.java)
30+
31+
/**
32+
* @see ListableBeanFactory.getBeansOfType(Class<T>, boolean, boolean)
33+
*/
34+
fun <T : Any> ListableBeanFactory.getBeansOfType(type: KClass<T>,
35+
includeNonSingletons: Boolean, allowEagerInit: Boolean) =
36+
getBeansOfType(type.java, includeNonSingletons, allowEagerInit)
37+
38+
/**
39+
* @see ListableBeanFactory.getBeanNamesForAnnotation
40+
*/
41+
fun <T : Annotation> ListableBeanFactory.getBeanNamesForAnnotation(type: KClass<T>) =
42+
getBeanNamesForAnnotation(type.java)
43+
44+
/**
45+
* @see ListableBeanFactory.getBeansWithAnnotation
46+
*/
47+
fun <T : Annotation> ListableBeanFactory.getBeansWithAnnotation(type: KClass<T>) =
48+
getBeansWithAnnotation(type.java)
49+
50+
/**
51+
* @see ListableBeanFactoryExtension.findAnnotationOnBean
52+
*/
53+
fun <T : Annotation> ListableBeanFactory.findAnnotationOnBean(beanName:String, type: KClass<T>) =
54+
findAnnotationOnBean(beanName, type.java)
55+
56+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
package org.springframework.context.support
2+
3+
import org.springframework.beans.factory.config.BeanDefinitionCustomizer
4+
import java.util.function.Supplier
5+
import kotlin.reflect.KClass
6+
7+
/**
8+
* Extension for [GenericApplicationContext] providing [KClass] based API and
9+
* avoiding specifying a class parameter for the [Supplier] based variant thanks to
10+
* Kotlin reified type parameters.
11+
*
12+
* @since 5.0
13+
*/
14+
object GenericApplicationContextExtension {
15+
16+
/**
17+
* @see GenericApplicationContext.registerBean(Class<T>, BeanDefinitionCustomizer...)
18+
*/
19+
fun <T : Any> GenericApplicationContext.registerBean(beanClass: KClass<T>,
20+
vararg customizers: BeanDefinitionCustomizer) {
21+
registerBean(beanClass.java, *customizers)
22+
}
23+
24+
/**
25+
* @see GenericApplicationContext.registerBean(String, Class<T>, BeanDefinitionCustomizer...)
26+
*/
27+
fun <T : Any> GenericApplicationContext.registerBean(beanName: String, beanClass: KClass<T>,
28+
vararg customizers: BeanDefinitionCustomizer) {
29+
registerBean(beanName, beanClass.java, *customizers)
30+
}
31+
32+
/**
33+
* @see GenericApplicationContext.registerBean(Class<T>, Supplier<T>, BeanDefinitionCustomizer...)
34+
*/
35+
inline fun <reified T : Any> GenericApplicationContext.registerBean(supplier: Supplier<T>,
36+
vararg customizers: BeanDefinitionCustomizer) {
37+
registerBean(T::class.java, supplier, *customizers)
38+
}
39+
40+
/**
41+
* @see GenericApplicationContext.registerBean(String, Class<T>, Supplier<T>, BeanDefinitionCustomizer...)
42+
*/
43+
inline fun <reified T : Any> GenericApplicationContext.registerBean(name: String,
44+
supplier: Supplier<T>, vararg customizers: BeanDefinitionCustomizer) {
45+
registerBean(name, T::class.java, supplier, *customizers)
46+
}
47+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
package org.springframework.context.support
2+
3+
import org.junit.Assert.assertNotNull
4+
import org.junit.Test
5+
import org.springframework.context.support.GenericApplicationContextExtension.registerBean
6+
import org.springframework.beans.factory.BeanFactoryExtension.getBean
7+
import java.util.function.Supplier
8+
9+
class GenericApplicationContextExtensionTests {
10+
11+
@Test
12+
fun registerBeanWithClass() {
13+
val context = GenericApplicationContext()
14+
context.registerBean(BeanA::class)
15+
context.refresh()
16+
assertNotNull(context.getBean(BeanA::class))
17+
}
18+
19+
@Test
20+
fun registerBeanWithNameAndClass() {
21+
val context = GenericApplicationContext()
22+
context.registerBean("a", BeanA::class)
23+
context.refresh()
24+
assertNotNull(context.getBean("a"))
25+
}
26+
27+
@Test
28+
fun registerBeanWithSupplier() {
29+
val context = GenericApplicationContext()
30+
context.registerBean(Supplier { BeanA() })
31+
context.refresh()
32+
assertNotNull(context.getBean(BeanA::class))
33+
}
34+
35+
@Test
36+
fun registerBeanWithNameAndSupplier() {
37+
val context = GenericApplicationContext()
38+
context.registerBean("a", Supplier { BeanA() })
39+
context.refresh()
40+
assertNotNull(context.getBean("a"))
41+
}
42+
43+
internal class BeanA
44+
45+
}

0 commit comments

Comments
 (0)