Add support for records in BindingReflectionHintsRegistrar
Closes gh-28721
This commit is contained in:
parent
89a6101b2e
commit
da68781b9e
|
@ -21,6 +21,7 @@ import java.beans.IntrospectionException;
|
|||
import java.beans.Introspector;
|
||||
import java.beans.PropertyDescriptor;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.RecordComponent;
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Set;
|
||||
|
@ -90,20 +91,28 @@ public class BindingReflectionHintsRegistrar {
|
|||
}
|
||||
seen.add(type);
|
||||
if (shouldRegisterMembers(clazz)) {
|
||||
builder.withMembers(
|
||||
MemberCategory.DECLARED_FIELDS,
|
||||
MemberCategory.INVOKE_DECLARED_CONSTRUCTORS);
|
||||
try {
|
||||
BeanInfo beanInfo = Introspector.getBeanInfo(clazz);
|
||||
PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
|
||||
for (PropertyDescriptor propertyDescriptor : propertyDescriptors) {
|
||||
registerPropertyHints(hints, seen, propertyDescriptor.getWriteMethod(), 0);
|
||||
registerPropertyHints(hints, seen, propertyDescriptor.getReadMethod(), -1);
|
||||
if (clazz.isRecord()) {
|
||||
builder.withMembers(MemberCategory.INVOKE_DECLARED_CONSTRUCTORS);
|
||||
for (RecordComponent recordComponent : clazz.getRecordComponents()) {
|
||||
registerRecordHints(hints, seen, recordComponent.getAccessor());
|
||||
}
|
||||
}
|
||||
catch (IntrospectionException ex) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Ignoring referenced type [" + clazz.getName() + "]: " + ex.getMessage());
|
||||
else {
|
||||
builder.withMembers(
|
||||
MemberCategory.DECLARED_FIELDS,
|
||||
MemberCategory.INVOKE_DECLARED_CONSTRUCTORS);
|
||||
try {
|
||||
BeanInfo beanInfo = Introspector.getBeanInfo(clazz);
|
||||
PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
|
||||
for (PropertyDescriptor propertyDescriptor : propertyDescriptors) {
|
||||
registerPropertyHints(hints, seen, propertyDescriptor.getWriteMethod(), 0);
|
||||
registerPropertyHints(hints, seen, propertyDescriptor.getReadMethod(), -1);
|
||||
}
|
||||
}
|
||||
catch (IntrospectionException ex) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Ignoring referenced type [" + clazz.getName() + "]: " + ex.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -115,6 +124,15 @@ public class BindingReflectionHintsRegistrar {
|
|||
referencedTypes.forEach(referencedType -> registerReflectionHints(hints, seen, referencedType));
|
||||
}
|
||||
|
||||
private void registerRecordHints(ReflectionHints hints, Set<Type> seen, Method method) {
|
||||
hints.registerMethod(method, INVOKE);
|
||||
MethodParameter methodParameter = MethodParameter.forExecutable(method, -1);
|
||||
Type methodParameterType = methodParameter.getGenericParameterType();
|
||||
if (!seen.contains(methodParameterType)) {
|
||||
registerReflectionHints(hints, seen, methodParameterType);
|
||||
}
|
||||
}
|
||||
|
||||
private void registerPropertyHints(ReflectionHints hints, Set<Type> seen, @Nullable Method method, int parameterIndex) {
|
||||
if (method != null && method.getDeclaringClass() != Object.class
|
||||
&& method.getDeclaringClass() != Enum.class) {
|
||||
|
|
|
@ -203,6 +203,26 @@ public class BindingReflectionHintsRegistrarTests {
|
|||
.satisfies(typeHint -> assertThat(typeHint.getType()).isEqualTo(TypeReference.of(SampleEnum.class)));
|
||||
}
|
||||
|
||||
@Test
|
||||
void registerTypeForSerializationWithRecord() {
|
||||
bindingRegistrar.registerReflectionHints(this.hints.reflection(), SampleRecord.class);
|
||||
assertThat(this.hints.reflection().typeHints()).satisfiesExactlyInAnyOrder(
|
||||
typeHint -> {
|
||||
assertThat(typeHint.getType()).isEqualTo(TypeReference.of(String.class));
|
||||
assertThat(typeHint.getMemberCategories()).isEmpty();
|
||||
assertThat(typeHint.constructors()).isEmpty();
|
||||
assertThat(typeHint.fields()).isEmpty();
|
||||
assertThat(typeHint.methods()).isEmpty();
|
||||
},
|
||||
typeHint -> {
|
||||
assertThat(typeHint.getType()).isEqualTo(TypeReference.of(SampleRecord.class));
|
||||
assertThat(typeHint.methods()).singleElement().satisfies(methodHint -> {
|
||||
assertThat(methodHint.getName()).isEqualTo("name");
|
||||
assertThat(methodHint.getModes()).containsOnly(ExecutableMode.INVOKE);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
static class SampleEmptyClass {
|
||||
}
|
||||
|
@ -285,4 +305,6 @@ public class BindingReflectionHintsRegistrarTests {
|
|||
value1, value2
|
||||
}
|
||||
|
||||
record SampleRecord(String name) {}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue