Browse Source

Fix BindingReflectionHintsRegistrar enum support

This commit prevents a StackOverflowError in
BindingReflectionHintsRegistrar when processing enum types
and refine related generated hints.

See gh-28683
pull/28715/head
Sébastien Deleuze 2 years ago
parent
commit
fb1aa4f5d5
  1. 8
      spring-core/src/main/java/org/springframework/aot/hint/support/BindingReflectionHintsRegistrar.java
  2. 11
      spring-core/src/test/java/org/springframework/aot/hint/support/BindingReflectionHintsRegistrarTests.java

8
spring-core/src/main/java/org/springframework/aot/hint/support/BindingReflectionHintsRegistrar.java

@ -98,7 +98,8 @@ public class BindingReflectionHintsRegistrar {
PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors(); PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
for (PropertyDescriptor propertyDescriptor : propertyDescriptors) { for (PropertyDescriptor propertyDescriptor : propertyDescriptors) {
Method writeMethod = propertyDescriptor.getWriteMethod(); Method writeMethod = propertyDescriptor.getWriteMethod();
if (writeMethod != null && writeMethod.getDeclaringClass() != Object.class) { if (writeMethod != null && writeMethod.getDeclaringClass() != Object.class
&& writeMethod.getDeclaringClass() != Enum.class) {
hints.registerMethod(writeMethod, INVOKE); hints.registerMethod(writeMethod, INVOKE);
MethodParameter methodParameter = MethodParameter.forExecutable(writeMethod, 0); MethodParameter methodParameter = MethodParameter.forExecutable(writeMethod, 0);
Type methodParameterType = methodParameter.getGenericParameterType(); Type methodParameterType = methodParameter.getGenericParameterType();
@ -107,7 +108,8 @@ public class BindingReflectionHintsRegistrar {
} }
} }
Method readMethod = propertyDescriptor.getReadMethod(); Method readMethod = propertyDescriptor.getReadMethod();
if (readMethod != null && readMethod.getDeclaringClass() != Object.class) { if (readMethod != null && readMethod.getDeclaringClass() != Object.class
&& readMethod.getDeclaringClass() != Enum.class) {
hints.registerMethod(readMethod, INVOKE); hints.registerMethod(readMethod, INVOKE);
MethodParameter methodParameter = MethodParameter.forExecutable(readMethod, -1); MethodParameter methodParameter = MethodParameter.forExecutable(readMethod, -1);
Type methodParameterType = methodParameter.getGenericParameterType(); Type methodParameterType = methodParameter.getGenericParameterType();
@ -144,7 +146,7 @@ public class BindingReflectionHintsRegistrar {
} }
ResolvableType resolvableType = ResolvableType.forType(type); ResolvableType resolvableType = ResolvableType.forType(type);
Class<?> clazz = resolvableType.resolve(); Class<?> clazz = resolvableType.resolve();
if (clazz != null) { if (clazz != null && !types.contains(clazz)) {
types.add(clazz); types.add(clazz);
for (ResolvableType genericResolvableType : resolvableType.getGenerics()) { for (ResolvableType genericResolvableType : resolvableType.getGenerics()) {
collectReferencedTypes(seen, types, genericResolvableType.getType()); collectReferencedTypes(seen, types, genericResolvableType.getType());

11
spring-core/src/test/java/org/springframework/aot/hint/support/BindingReflectionHintsRegistrarTests.java

@ -196,6 +196,13 @@ public class BindingReflectionHintsRegistrarTests {
typeHint -> assertThat(typeHint.getType()).isEqualTo(TypeReference.of(Set.class))); typeHint -> assertThat(typeHint.getType()).isEqualTo(TypeReference.of(Set.class)));
} }
@Test
void registerTypeForSerializationWithEnum() {
bindingRegistrar.registerReflectionHints(this.hints.reflection(), SampleEnum.class);
assertThat(this.hints.reflection().typeHints()).singleElement()
.satisfies(typeHint -> assertThat(typeHint.getType()).isEqualTo(TypeReference.of(SampleEnum.class)));
}
static class SampleEmptyClass { static class SampleEmptyClass {
} }
@ -274,4 +281,8 @@ public class BindingReflectionHintsRegistrarTests {
} }
} }
enum SampleEnum {
value1, value2
}
} }

Loading…
Cancel
Save