Skip to content

Commit 4977ef9

Browse files
committed
Import ConstructorResolver to handle null values
Previously, ConstructorResolver would reject any candidate if the parameter is `null`. The reason for that is that null does not carry any type and the matching algorithm would systematically fail for that argument. This commit adds an extra check, and several tests, to validate that a null value is taken into account. Closes gh-31495
1 parent fe7b6dd commit 4977ef9

File tree

2 files changed

+48
-1
lines changed

2 files changed

+48
-1
lines changed

spring-beans/src/main/java/org/springframework/beans/factory/support/ConstructorResolver.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1200,7 +1200,8 @@ private boolean isMatch(ResolvableType parameterType, ResolvableType valueType,
12001200
}
12011201

12021202
private Predicate<ResolvableType> isAssignable(ResolvableType valueType) {
1203-
return parameterType -> parameterType.isAssignableFrom(valueType);
1203+
return parameterType -> (valueType == ResolvableType.NONE
1204+
|| parameterType.isAssignableFrom(valueType));
12041205
}
12051206

12061207
private ResolvableType extractElementType(ResolvableType parameterType) {

spring-beans/src/test/java/org/springframework/beans/factory/support/ConstructorResolverAotTests.java

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -414,6 +414,43 @@ void beanDefinitionWithClassArrayFactoryMethodArgAndAnotherMatchingConstructor()
414414
String[].class));
415415
}
416416

417+
@Test
418+
void beanDefinitionWithMultiConstructorSimilarArgumentsAndMatchingValues() throws NoSuchMethodException {
419+
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
420+
BeanDefinition beanDefinition = BeanDefinitionBuilder
421+
.rootBeanDefinition(MultiConstructorSimilarArgumentsSample.class)
422+
.addConstructorArgValue("Test").addConstructorArgValue(1).addConstructorArgValue(2)
423+
.getBeanDefinition();
424+
Executable executable = resolve(beanFactory, beanDefinition);
425+
assertThat(executable).isNotNull()
426+
.isEqualTo(MultiConstructorSimilarArgumentsSample.class
427+
.getDeclaredConstructor(String.class, Integer.class, Integer.class));
428+
}
429+
430+
@Test
431+
void beanDefinitionWithMultiConstructorSimilarArgumentsAndNullValueForCommonArgument() throws NoSuchMethodException {
432+
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
433+
BeanDefinition beanDefinition = BeanDefinitionBuilder
434+
.rootBeanDefinition(MultiConstructorSimilarArgumentsSample.class)
435+
.addConstructorArgValue(null).addConstructorArgValue(null).addConstructorArgValue("Test")
436+
.getBeanDefinition();
437+
Executable executable = resolve(beanFactory, beanDefinition);
438+
assertThat(executable).isNotNull()
439+
.isEqualTo(MultiConstructorSimilarArgumentsSample.class
440+
.getDeclaredConstructor(String.class, Integer.class, String.class));
441+
}
442+
443+
@Test
444+
void beanDefinitionWithMultiConstructorSimilarArgumentsAndNullValueForSpecificArgument() throws NoSuchMethodException {
445+
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
446+
BeanDefinition beanDefinition = BeanDefinitionBuilder
447+
.rootBeanDefinition(MultiConstructorSimilarArgumentsSample.class)
448+
.addConstructorArgValue(null).addConstructorArgValue(1).addConstructorArgValue(null)
449+
.getBeanDefinition();
450+
assertThatIllegalStateException().isThrownBy(() -> resolve(beanFactory, beanDefinition))
451+
.withMessageContaining(MultiConstructorSimilarArgumentsSample.class.getName());
452+
}
453+
417454
@Test
418455
void beanDefinitionWithMultiArgConstructorAndPrimitiveConversion() throws NoSuchMethodException {
419456
BeanDefinition beanDefinition = BeanDefinitionBuilder
@@ -534,6 +571,15 @@ static class MultiConstructorClassArraySample {
534571
}
535572
}
536573

574+
static class MultiConstructorSimilarArgumentsSample {
575+
576+
MultiConstructorSimilarArgumentsSample(String name, Integer counter, String value) {
577+
}
578+
579+
MultiConstructorSimilarArgumentsSample(String name, Integer counter, Integer value) {
580+
}
581+
}
582+
537583
@SuppressWarnings("unused")
538584
static class ClassArrayFactoryMethodSample {
539585

0 commit comments

Comments
 (0)