Improve support of Kotlin beans w/ primary and default ctors

This commit add the default constructor if available as
fallback after to the primary constructor.

Issue: SPR-16012
master
Sebastien Deleuze 7 years ago
parent ec5969c578
commit fb09a75c82
  1. 4
      spring-beans/src/main/java/org/springframework/beans/factory/annotation/AutowiredAnnotationBeanPostProcessor.java
  2. 35
      spring-beans/src/test/kotlin/org/springframework/beans/factory/annotation/KotlinAutowiredTests.kt

@ -367,7 +367,9 @@ public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBean
candidateConstructors = new Constructor<?>[] {rawCandidates[0]};
}
else if (kotlinPrimaryConstructor != null) {
candidateConstructors = new Constructor<?>[] {kotlinPrimaryConstructor};
candidateConstructors = (defaultConstructor != null ?
new Constructor<?>[] {kotlinPrimaryConstructor, defaultConstructor} :
new Constructor<?>[] {kotlinPrimaryConstructor});
}
else {
candidateConstructors = new Constructor<?>[0];

@ -122,6 +122,36 @@ class KotlinAutowiredTests {
assertSame(colour, kb.injectedFromSecondaryConstructor)
}
@Test // SPR-16012
fun `Fallback on the default constructor when no autowirable primary constructor is defined`() {
val bf = DefaultListableBeanFactory()
val bpp = AutowiredAnnotationBeanPostProcessor()
bpp.setBeanFactory(bf)
bf.addBeanPostProcessor(bpp)
val bd = RootBeanDefinition(KotlinBeanWithPrimaryAndDefaultConstructors::class.java)
bd.scope = RootBeanDefinition.SCOPE_PROTOTYPE
bf.registerBeanDefinition("bean", bd)
val kb = bf.getBean("bean", KotlinBeanWithPrimaryAndDefaultConstructors::class.java)
assertNotNull(kb.testBean)
}
@Test // SPR-16012
fun `Instantiation via primary constructor when a default is defined`() {
val bf = DefaultListableBeanFactory()
val bpp = AutowiredAnnotationBeanPostProcessor()
bpp.setBeanFactory(bf)
bf.addBeanPostProcessor(bpp)
val bd = RootBeanDefinition(KotlinBeanWithPrimaryAndDefaultConstructors::class.java)
bd.scope = RootBeanDefinition.SCOPE_PROTOTYPE
bf.registerBeanDefinition("bean", bd)
val tb = TestBean()
bf.registerSingleton("testBean", tb)
val kb = bf.getBean("bean", KotlinBeanWithPrimaryAndDefaultConstructors::class.java)
assertEquals(tb, kb.testBean)
}
class KotlinBean(val injectedFromConstructor: TestBean?) {
@ -163,4 +193,9 @@ class KotlinAutowiredTests {
var injectedFromSecondaryConstructor: Colour? = null
}
@Suppress("unused")
class KotlinBeanWithPrimaryAndDefaultConstructors(val testBean: TestBean) {
constructor() : this(TestBean())
}
}

Loading…
Cancel
Save