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
This commit is contained in:
parent
fe7b6ddf88
commit
4977ef9cea
|
@ -1200,7 +1200,8 @@ class ConstructorResolver {
|
|||
}
|
||||
|
||||
private Predicate<ResolvableType> isAssignable(ResolvableType valueType) {
|
||||
return parameterType -> parameterType.isAssignableFrom(valueType);
|
||||
return parameterType -> (valueType == ResolvableType.NONE
|
||||
|| parameterType.isAssignableFrom(valueType));
|
||||
}
|
||||
|
||||
private ResolvableType extractElementType(ResolvableType parameterType) {
|
||||
|
|
|
@ -414,6 +414,43 @@ class ConstructorResolverAotTests {
|
|||
String[].class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void beanDefinitionWithMultiConstructorSimilarArgumentsAndMatchingValues() throws NoSuchMethodException {
|
||||
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
|
||||
BeanDefinition beanDefinition = BeanDefinitionBuilder
|
||||
.rootBeanDefinition(MultiConstructorSimilarArgumentsSample.class)
|
||||
.addConstructorArgValue("Test").addConstructorArgValue(1).addConstructorArgValue(2)
|
||||
.getBeanDefinition();
|
||||
Executable executable = resolve(beanFactory, beanDefinition);
|
||||
assertThat(executable).isNotNull()
|
||||
.isEqualTo(MultiConstructorSimilarArgumentsSample.class
|
||||
.getDeclaredConstructor(String.class, Integer.class, Integer.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void beanDefinitionWithMultiConstructorSimilarArgumentsAndNullValueForCommonArgument() throws NoSuchMethodException {
|
||||
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
|
||||
BeanDefinition beanDefinition = BeanDefinitionBuilder
|
||||
.rootBeanDefinition(MultiConstructorSimilarArgumentsSample.class)
|
||||
.addConstructorArgValue(null).addConstructorArgValue(null).addConstructorArgValue("Test")
|
||||
.getBeanDefinition();
|
||||
Executable executable = resolve(beanFactory, beanDefinition);
|
||||
assertThat(executable).isNotNull()
|
||||
.isEqualTo(MultiConstructorSimilarArgumentsSample.class
|
||||
.getDeclaredConstructor(String.class, Integer.class, String.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void beanDefinitionWithMultiConstructorSimilarArgumentsAndNullValueForSpecificArgument() throws NoSuchMethodException {
|
||||
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
|
||||
BeanDefinition beanDefinition = BeanDefinitionBuilder
|
||||
.rootBeanDefinition(MultiConstructorSimilarArgumentsSample.class)
|
||||
.addConstructorArgValue(null).addConstructorArgValue(1).addConstructorArgValue(null)
|
||||
.getBeanDefinition();
|
||||
assertThatIllegalStateException().isThrownBy(() -> resolve(beanFactory, beanDefinition))
|
||||
.withMessageContaining(MultiConstructorSimilarArgumentsSample.class.getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
void beanDefinitionWithMultiArgConstructorAndPrimitiveConversion() throws NoSuchMethodException {
|
||||
BeanDefinition beanDefinition = BeanDefinitionBuilder
|
||||
|
@ -534,6 +571,15 @@ class ConstructorResolverAotTests {
|
|||
}
|
||||
}
|
||||
|
||||
static class MultiConstructorSimilarArgumentsSample {
|
||||
|
||||
MultiConstructorSimilarArgumentsSample(String name, Integer counter, String value) {
|
||||
}
|
||||
|
||||
MultiConstructorSimilarArgumentsSample(String name, Integer counter, Integer value) {
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
static class ClassArrayFactoryMethodSample {
|
||||
|
||||
|
|
Loading…
Reference in New Issue