Refine BindingReflectionHintsRegistrar

This commit refines BindingReflectionHintsRegistrar to skip
registration of hints for Object.class, primitive types and
skip members for array types.

Closes gh-28683
This commit is contained in:
Sébastien Deleuze
2022-06-23 15:42:09 +02:00
parent 61e9aa9f42
commit b121eed753
2 changed files with 56 additions and 1 deletions

View File

@@ -76,11 +76,14 @@ public class BindingReflectionHintsRegistrar {
* @return {@code true} if the members of the type should be registered transitively
*/
protected boolean shouldRegisterMembers(Class<?> type) {
return !type.getCanonicalName().startsWith("java.");
return !type.getCanonicalName().startsWith("java.") && !type.isArray();
}
private void registerReflectionHints(ReflectionHints hints, Set<Type> seen, Type type) {
if (type instanceof Class<?> clazz) {
if (clazz.isPrimitive() || clazz == Object.class) {
return;
}
hints.registerType(clazz, builder -> {
if (seen.contains(type)) {
return;

View File

@@ -16,6 +16,7 @@
package org.springframework.aot.hint.support;
import java.lang.reflect.Type;
import java.util.List;
import org.junit.jupiter.api.Test;
@@ -24,6 +25,7 @@ import org.springframework.aot.hint.ExecutableMode;
import org.springframework.aot.hint.MemberCategory;
import org.springframework.aot.hint.RuntimeHints;
import org.springframework.aot.hint.TypeReference;
import org.springframework.core.ResolvableType;
import static org.assertj.core.api.Assertions.assertThat;
@@ -139,6 +141,49 @@ public class BindingReflectionHintsRegistrarTests {
typeHint -> assertThat(typeHint.getType()).isEqualTo(TypeReference.of(List.class)));
}
@Test
void registerTypeForSerializationWithResolvableType() {
bindingRegistrar.registerReflectionHints(this.hints.reflection(), SampleClassWithResolvableType.class);
assertThat(this.hints.reflection().typeHints()).satisfiesExactlyInAnyOrder(
typeHint -> {
assertThat(typeHint.getType()).isEqualTo(TypeReference.of(ResolvableType[].class));
assertThat(typeHint.getMemberCategories()).isEmpty();
assertThat(typeHint.constructors()).isEmpty();
assertThat(typeHint.fields()).isEmpty();
assertThat(typeHint.methods()).isEmpty();
},
typeHint -> {
assertThat(typeHint.getType()).isEqualTo(TypeReference.of(Type.class));
assertThat(typeHint.getMemberCategories()).isEmpty();
assertThat(typeHint.constructors()).isEmpty();
assertThat(typeHint.fields()).isEmpty();
assertThat(typeHint.methods()).isEmpty();
},
typeHint -> {
assertThat(typeHint.getType()).isEqualTo(TypeReference.of(Class.class));
assertThat(typeHint.getMemberCategories()).isEmpty();
assertThat(typeHint.constructors()).isEmpty();
assertThat(typeHint.fields()).isEmpty();
assertThat(typeHint.methods()).isEmpty();
},
typeHint -> {
assertThat(typeHint.getType()).isEqualTo(TypeReference.of(ResolvableType.class));
assertThat(typeHint.getMemberCategories()).containsExactlyInAnyOrder(
MemberCategory.DECLARED_FIELDS, MemberCategory.INVOKE_DECLARED_CONSTRUCTORS);
assertThat(typeHint.constructors()).isEmpty();
assertThat(typeHint.fields()).isEmpty();
assertThat(typeHint.methods()).hasSizeGreaterThan(1);
},
typeHint -> {
assertThat(typeHint.getType()).isEqualTo(TypeReference.of(SampleClassWithResolvableType.class));
assertThat(typeHint.methods()).singleElement().satisfies(
methodHint -> {
assertThat(methodHint.getName()).isEqualTo("getResolvableType");
assertThat(methodHint.getModes()).containsOnly(ExecutableMode.INVOKE);
});
});
}
static class SampleEmptyClass {
}
@@ -192,4 +237,11 @@ public class BindingReflectionHintsRegistrarTests {
}
}
static class SampleClassWithResolvableType {
public ResolvableType getResolvableType() {
return null;
}
}
}