Skip to content
This repository was archived by the owner on Feb 23, 2023. It is now read-only.

Commit 4e204a9

Browse files
committed
Enhance constructor resolution with use of SpEL
Closes gh-1229
1 parent e05e14b commit 4e204a9

File tree

2 files changed

+46
-4
lines changed

2 files changed

+46
-4
lines changed

spring-aot/src/main/java/org/springframework/aot/context/bootstrap/generator/bean/descriptor/BeanInstanceExecutableSupplier.java

+25-3
Original file line numberDiff line numberDiff line change
@@ -267,13 +267,23 @@ private ResolvableType extractElementType(ResolvableType parameterType) {
267267

268268
private Predicate<ResolvableType> typeConversionFallback(ResolvableType valueType) {
269269
return (parameterType) -> {
270-
if (isStringForClassFallback(valueType).test(parameterType)) {
270+
if (valueOrCollection(valueType, this::isStringForClassFallback).test(parameterType)) {
271271
return true;
272272
}
273-
if (isStringForClassFallback(extractElementType(valueType)).test(extractElementType(parameterType))) {
273+
return valueOrCollection(valueType, this::isSimpleConvertibleType).test(parameterType);
274+
};
275+
}
276+
277+
private Predicate<ResolvableType> valueOrCollection(ResolvableType valueType,
278+
Function<ResolvableType, Predicate<ResolvableType>> predicateProvider) {
279+
return (parameterType) -> {
280+
if (predicateProvider.apply(valueType).test(parameterType)) {
281+
return true;
282+
}
283+
if (predicateProvider.apply(extractElementType(valueType)).test(extractElementType(parameterType))) {
274284
return true;
275285
}
276-
return (isStringForClassFallback(valueType).test(extractElementType(parameterType)));
286+
return (predicateProvider.apply(valueType).test(extractElementType(parameterType)));
277287
};
278288
}
279289

@@ -289,6 +299,10 @@ private Predicate<ResolvableType> isStringForClassFallback(ResolvableType valueT
289299
&& parameterType.isAssignableFrom(Class.class));
290300
}
291301

302+
private Predicate<ResolvableType> isSimpleConvertibleType(ResolvableType valueType) {
303+
return (parameterType) -> isSimpleConvertibleType(parameterType.toClass()) && isSimpleConvertibleType(valueType.toClass());
304+
}
305+
292306
private Class<?> getFactoryBeanClass(BeanDefinition beanDefinition) {
293307
if (beanDefinition instanceof RootBeanDefinition) {
294308
RootBeanDefinition rbd = (RootBeanDefinition) beanDefinition;
@@ -333,6 +347,14 @@ private <T> T getField(BeanDefinition beanDefinition, String fieldName, Class<T>
333347
return targetType.cast(ReflectionUtils.getField(field, beanDefinition));
334348
}
335349

350+
public static boolean isSimpleConvertibleType(Class<?> type) {
351+
return (type.isPrimitive() && type != void.class) ||
352+
type == Double.class || type == Float.class || type == Long.class ||
353+
type == Integer.class || type == Short.class || type == Character.class ||
354+
type == Byte.class || type == Boolean.class || type == String.class;
355+
}
356+
357+
336358
enum FallbackMode {
337359

338360
NONE,

spring-aot/src/test/java/org/springframework/aot/context/bootstrap/generator/bean/descriptor/BeanInstanceExecutableSupplierTests.java

+21-1
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import java.lang.reflect.Executable;
2020
import java.util.List;
2121
import java.util.Locale;
22+
import java.util.concurrent.Executor;
2223

2324
import org.junit.jupiter.api.Test;
2425

@@ -249,6 +250,14 @@ void beanDefinitionWithClassArrayFactoryMethodArgAndAnotherMatchingConstructor()
249250
.findMethod(ClassArrayFactoryMethodSampleWithAnotherFactoryMethod.class, "of", String[].class));
250251
}
251252

253+
@Test
254+
void beanDefinitionWithMultiArgConstructorAndPrimitiveConversion() throws NoSuchMethodException {
255+
BeanDefinition beanDefinition = BeanDefinitionBuilder.rootBeanDefinition(ConstructorPrimitiveFallback.class)
256+
.addConstructorArgValue("true").getBeanDefinition();
257+
Executable executable = detectBeanInstanceExecutable(new DefaultListableBeanFactory(), beanDefinition);
258+
assertThat(executable).isEqualTo(ConstructorPrimitiveFallback.class.getDeclaredConstructor(boolean.class));
259+
}
260+
252261
private Executable detectBeanInstanceExecutable(DefaultListableBeanFactory beanFactory, BeanDefinition beanDefinition) {
253262
return new BeanInstanceExecutableSupplier(beanFactory).detectBeanInstanceExecutable(beanDefinition);
254263
}
@@ -322,7 +331,7 @@ static class ConstructorClassArraySample {
322331
ConstructorClassArraySample(Class<?>... classArrayArg) {
323332
}
324333

325-
ConstructorClassArraySample(Integer somethingElse) {
334+
ConstructorClassArraySample(Executor somethingElse) {
326335
}
327336
}
328337

@@ -357,4 +366,15 @@ static String of(String[] classArrayArg) {
357366
}
358367

359368
}
369+
370+
@SuppressWarnings("unnused")
371+
static class ConstructorPrimitiveFallback {
372+
373+
public ConstructorPrimitiveFallback(boolean useDefaultExecutor) {
374+
}
375+
376+
public ConstructorPrimitiveFallback(Executor executor) {
377+
}
378+
379+
}
360380
}

0 commit comments

Comments
 (0)