Consider all processors when processing @Reflective

Previously, only the first occurance of `@Reflective` and its
processor was considered. When `@Reflective` appeared twice on a type
due to meta-annotations or inheritance, this resulted in other
processors being ignored and hints were missing as a result.

This commit updates ReflectiveRuntimeHintsRegistrar to consider
every occurance of `@Reflective` found in the type hierarchy,
and to then use the processors from each of them.

Fixes gh-29193
This commit is contained in:
Andy Wilkinson
2022-09-23 15:19:47 +01:00
committed by Sébastien Deleuze
parent c19cedede1
commit a409e0fd2c
2 changed files with 48 additions and 5 deletions

View File

@@ -25,6 +25,8 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.Consumer;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.springframework.aot.hint.ReflectionHints;
import org.springframework.aot.hint.RuntimeHints;
@@ -36,6 +38,7 @@ import org.springframework.util.ReflectionUtils;
* Process {@link Reflective} annotated elements.
*
* @author Stephane Nicoll
* @author Andy Wilkinson
* since 6.0
*/
public class ReflectiveRuntimeHintsRegistrar {
@@ -89,9 +92,11 @@ public class ReflectiveRuntimeHintsRegistrar {
@SuppressWarnings("unchecked")
private Entry createEntry(AnnotatedElement element) {
Class<? extends ReflectiveProcessor>[] processorClasses = (Class<? extends ReflectiveProcessor>[])
MergedAnnotations.from(element, MergedAnnotations.SearchStrategy.TYPE_HIERARCHY).get(Reflective.class).getClassArray("value");
List<ReflectiveProcessor> processors = Arrays.stream(processorClasses).distinct()
List<Class<? extends ReflectiveProcessor>> processorClasses =
MergedAnnotations.from(element, MergedAnnotations.SearchStrategy.TYPE_HIERARCHY)
.stream(Reflective.class).flatMap(annotation -> Stream.of(annotation.getClassArray("value")))
.map(type -> (Class<? extends ReflectiveProcessor>) type).collect(Collectors.toList());
List<ReflectiveProcessor> processors = processorClasses.stream().distinct()
.map(processorClass -> this.processors.computeIfAbsent(processorClass, this::instantiateClass))
.toList();
ReflectiveProcessor processorToUse = (processors.size() == 1 ? processors.get(0)