Polish
This commit is contained in:
parent
d6d4b98780
commit
77ad4a1428
|
@ -34,14 +34,16 @@ import org.springframework.aot.hint.ExecutableHint;
|
||||||
import org.springframework.aot.hint.ExecutableMode;
|
import org.springframework.aot.hint.ExecutableMode;
|
||||||
import org.springframework.aot.hint.MemberCategory;
|
import org.springframework.aot.hint.MemberCategory;
|
||||||
import org.springframework.aot.hint.ReflectionHints;
|
import org.springframework.aot.hint.ReflectionHints;
|
||||||
|
import org.springframework.aot.hint.TypeHint.Builder;
|
||||||
import org.springframework.core.MethodParameter;
|
import org.springframework.core.MethodParameter;
|
||||||
import org.springframework.core.ResolvableType;
|
import org.springframework.core.ResolvableType;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Register the necessary reflection hints so that the specified type can be bound/serialized at runtime.
|
* Register the necessary reflection hints so that the specified type can be
|
||||||
* Fields, constructors and property methods are registered, except for a set of types like those in
|
* bound at runtime. Fields, constructors and property methods are registered,
|
||||||
* {@code java.} package where just the type is registered. Types are discovered transitively and
|
* except for a set of types like those in the {@code java.} package where just
|
||||||
* generic types are registered as well.
|
* the type is registered. Types are discovered transitively and generic types
|
||||||
|
* are registered as well.
|
||||||
*
|
*
|
||||||
* @author Sebastien Deleuze
|
* @author Sebastien Deleuze
|
||||||
* @since 6.0
|
* @since 6.0
|
||||||
|
@ -53,38 +55,22 @@ public class BindingReflectionHintsRegistrar {
|
||||||
private static final Consumer<ExecutableHint.Builder> INVOKE = builder -> builder
|
private static final Consumer<ExecutableHint.Builder> INVOKE = builder -> builder
|
||||||
.withMode(ExecutableMode.INVOKE);
|
.withMode(ExecutableMode.INVOKE);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register the necessary reflection hints to bind the specified types.
|
||||||
|
* @param hints the hints instance to use
|
||||||
|
* @param types the types to bind
|
||||||
|
*/
|
||||||
public void registerReflectionHints(ReflectionHints hints, Type... types) {
|
public void registerReflectionHints(ReflectionHints hints, Type... types) {
|
||||||
for (Type type : types) {
|
for (Type type : types) {
|
||||||
Set<Class<?>> referencedTypes = new LinkedHashSet<>();
|
Set<Class<?>> referencedTypes = new LinkedHashSet<>();
|
||||||
collectReferencedTypes(new HashSet<>(), referencedTypes, type);
|
collectReferencedTypes(new HashSet<>(), referencedTypes, type);
|
||||||
referencedTypes.forEach(referencedType -> hints.registerType(referencedType, builder -> {
|
for (Class<?> referencedType : referencedTypes) {
|
||||||
if (shouldRegisterMembers(referencedType)) {
|
hints.registerType(referencedType, builder -> {
|
||||||
builder.withMembers(MemberCategory.DECLARED_FIELDS, MemberCategory.INVOKE_DECLARED_CONSTRUCTORS);
|
if (shouldRegisterMembers(referencedType)) {
|
||||||
try {
|
registerMembers(hints, referencedType, builder);
|
||||||
BeanInfo beanInfo = Introspector.getBeanInfo(referencedType);
|
|
||||||
PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
|
|
||||||
for (PropertyDescriptor propertyDescriptor : propertyDescriptors) {
|
|
||||||
Method writeMethod = propertyDescriptor.getWriteMethod();
|
|
||||||
if (writeMethod != null && writeMethod.getDeclaringClass() != Object.class) {
|
|
||||||
hints.registerMethod(writeMethod, INVOKE);
|
|
||||||
MethodParameter methodParameter = MethodParameter.forExecutable(writeMethod, 0);
|
|
||||||
registerReflectionHints(hints, methodParameter.getGenericParameterType());
|
|
||||||
}
|
|
||||||
Method readMethod = propertyDescriptor.getReadMethod();
|
|
||||||
if (readMethod != null && readMethod.getDeclaringClass() != Object.class) {
|
|
||||||
hints.registerMethod(readMethod, INVOKE);
|
|
||||||
MethodParameter methodParameter = MethodParameter.forExecutable(readMethod, -1);
|
|
||||||
registerReflectionHints(hints, methodParameter.getGenericParameterType());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
catch (IntrospectionException ex) {
|
});
|
||||||
if (logger.isDebugEnabled()) {
|
}
|
||||||
logger.debug("Ignoring referenced type [" + referencedType.getName() + "]: " + ex.getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -97,13 +83,41 @@ public class BindingReflectionHintsRegistrar {
|
||||||
return !type.getCanonicalName().startsWith("java.");
|
return !type.getCanonicalName().startsWith("java.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void registerMembers(ReflectionHints hints, Class<?> type, Builder builder) {
|
||||||
|
builder.withMembers(MemberCategory.DECLARED_FIELDS,
|
||||||
|
MemberCategory.INVOKE_DECLARED_CONSTRUCTORS);
|
||||||
|
try {
|
||||||
|
BeanInfo beanInfo = Introspector.getBeanInfo(type);
|
||||||
|
PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
|
||||||
|
for (PropertyDescriptor propertyDescriptor : propertyDescriptors) {
|
||||||
|
Method writeMethod = propertyDescriptor.getWriteMethod();
|
||||||
|
if (writeMethod != null && writeMethod.getDeclaringClass() != Object.class) {
|
||||||
|
hints.registerMethod(writeMethod, INVOKE);
|
||||||
|
MethodParameter methodParameter = MethodParameter.forExecutable(writeMethod, 0);
|
||||||
|
registerReflectionHints(hints, methodParameter.getGenericParameterType());
|
||||||
|
}
|
||||||
|
Method readMethod = propertyDescriptor.getReadMethod();
|
||||||
|
if (readMethod != null && readMethod.getDeclaringClass() != Object.class) {
|
||||||
|
hints.registerMethod(readMethod, INVOKE);
|
||||||
|
MethodParameter methodParameter = MethodParameter.forExecutable(readMethod, -1);
|
||||||
|
registerReflectionHints(hints, methodParameter.getGenericParameterType());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (IntrospectionException ex) {
|
||||||
|
if (logger.isDebugEnabled()) {
|
||||||
|
logger.debug("Ignoring referenced type [" + type.getName() + "]: " + ex.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void collectReferencedTypes(Set<Type> seen, Set<Class<?>> types, Type type) {
|
private void collectReferencedTypes(Set<Type> seen, Set<Class<?>> types, Type type) {
|
||||||
if (seen.contains(type)) {
|
if (seen.contains(type)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
seen.add(type);
|
seen.add(type);
|
||||||
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.add(clazz);
|
types.add(clazz);
|
||||||
for (ResolvableType genericResolvableType : resolvableType.getGenerics()) {
|
for (ResolvableType genericResolvableType : resolvableType.getGenerics()) {
|
||||||
|
|
|
@ -35,6 +35,7 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||||
public class BindingReflectionHintsRegistrarTests {
|
public class BindingReflectionHintsRegistrarTests {
|
||||||
|
|
||||||
private final BindingReflectionHintsRegistrar bindingRegistrar = new BindingReflectionHintsRegistrar();
|
private final BindingReflectionHintsRegistrar bindingRegistrar = new BindingReflectionHintsRegistrar();
|
||||||
|
|
||||||
private final RuntimeHints hints = new RuntimeHints();
|
private final RuntimeHints hints = new RuntimeHints();
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
|
@ -34,14 +34,13 @@ import org.springframework.core.annotation.AnnotatedElementUtils;
|
||||||
* with {@link ResponseBody} and parameters annotated with {@link RequestBody}
|
* with {@link ResponseBody} and parameters annotated with {@link RequestBody}
|
||||||
* which are serialized as well.
|
* which are serialized as well.
|
||||||
*
|
*
|
||||||
*
|
|
||||||
* @author Stephane Nicoll
|
* @author Stephane Nicoll
|
||||||
* @author Sebastien Deleuze
|
* @author Sebastien Deleuze
|
||||||
* @since 6.0
|
* @since 6.0
|
||||||
*/
|
*/
|
||||||
class RequestMappingReflectiveProcessor implements ReflectiveProcessor {
|
class RequestMappingReflectiveProcessor implements ReflectiveProcessor {
|
||||||
|
|
||||||
private BindingReflectionHintsRegistrar bindingRegistrar = new BindingReflectionHintsRegistrar();
|
private final BindingReflectionHintsRegistrar bindingRegistrar = new BindingReflectionHintsRegistrar();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void registerReflectionHints(ReflectionHints hints, AnnotatedElement element) {
|
public void registerReflectionHints(ReflectionHints hints, AnnotatedElement element) {
|
||||||
|
|
Loading…
Reference in New Issue