Add support for Jackson annotations in BindingReflectionHintsRegistrar

This commits registers reflection hints on field and methods
where Jackson annotations are detected.

Closes gh-29426
This commit is contained in:
Sébastien Deleuze
2022-11-08 16:19:06 +01:00
parent 2878ade980
commit 60c9f2f72f
3 changed files with 73 additions and 2 deletions

View File

@@ -16,6 +16,7 @@
package org.springframework.aot.hint;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.RecordComponent;
import java.lang.reflect.Type;
@@ -28,8 +29,11 @@ import kotlin.reflect.KClass;
import org.springframework.core.KotlinDetector;
import org.springframework.core.MethodParameter;
import org.springframework.core.ResolvableType;
import org.springframework.core.annotation.MergedAnnotation;
import org.springframework.core.annotation.MergedAnnotations;
import org.springframework.lang.Nullable;
import org.springframework.util.ClassUtils;
import org.springframework.util.ReflectionUtils;
/**
* Register the necessary reflection hints so that the specified type can be
@@ -45,6 +49,11 @@ public class BindingReflectionHintsRegistrar {
private static final String KOTLIN_COMPANION_SUFFIX = "$Companion";
private static final String JACKSON_ANNOTATION = "com.fasterxml.jackson.annotation.JacksonAnnotation";
private static final boolean jacksonAnnotationPresent = ClassUtils.isPresent(JACKSON_ANNOTATION,
BindingReflectionHintsRegistrar.class.getClassLoader());
/**
* Register the necessary reflection hints to bind the specified types.
* @param hints the hints instance to use
@@ -97,6 +106,9 @@ public class BindingReflectionHintsRegistrar {
}
}
}
if (jacksonAnnotationPresent) {
registerJacksonHints(hints, clazz);
}
}
if (KotlinDetector.isKotlinType(clazz)) {
KotlinDelegate.registerComponentHints(hints, clazz);
@@ -147,6 +159,31 @@ public class BindingReflectionHintsRegistrar {
}
}
private void registerJacksonHints(ReflectionHints hints, Class<?> clazz) {
ReflectionUtils.doWithFields(clazz, field ->
MergedAnnotations
.from(field, MergedAnnotations.SearchStrategy.TYPE_HIERARCHY)
.stream(JACKSON_ANNOTATION)
.filter(MergedAnnotation::isMetaPresent)
.forEach(annotation -> {
Field sourceField = (Field) annotation.getSource();
if (sourceField != null) {
hints.registerField(sourceField);
}
}));
ReflectionUtils.doWithMethods(clazz, method ->
MergedAnnotations
.from(method, MergedAnnotations.SearchStrategy.TYPE_HIERARCHY)
.stream(JACKSON_ANNOTATION)
.filter(MergedAnnotation::isMetaPresent)
.forEach(annotation -> {
Method sourceMethod = (Method) annotation.getSource();
if (sourceMethod != null) {
hints.registerMethod(sourceMethod, ExecutableMode.INVOKE);
}
}));
}
/**
* Inner class to avoid a hard dependency on Kotlin at runtime.
*/