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

@@ -28,6 +28,7 @@ import org.junit.jupiter.api.Test;
import org.springframework.aot.hint.MemberCategory;
import org.springframework.aot.hint.ReflectionHints;
import org.springframework.aot.hint.RuntimeHints;
import org.springframework.aot.hint.TypeHint;
import org.springframework.aot.hint.TypeReference;
import org.springframework.aot.hint.predicate.RuntimeHintsPredicates;
import org.springframework.core.annotation.AliasFor;
@@ -40,6 +41,7 @@ import static org.mockito.Mockito.verifyNoInteractions;
* Tests for {@link ReflectiveRuntimeHintsRegistrar}.
*
* @author Stephane Nicoll
* @author Andy Wilkinson
*/
class ReflectiveRuntimeHintsRegistrarTests {
@@ -61,6 +63,14 @@ class ReflectiveRuntimeHintsRegistrarTests {
.isNotNull();
}
@Test
void shouldProcessWithMultipleProcessorsWithAnnotationOnType() {
process(SampleMultipleCustomProcessors.class);
TypeHint typeHint = this.runtimeHints.reflection().getTypeHint(SampleMultipleCustomProcessors.class);
assertThat(typeHint).isNotNull();
assertThat(typeHint.getMemberCategories()).containsExactly(MemberCategory.INVOKE_DECLARED_METHODS);
}
@Test
void shouldProcessAnnotationOnConstructor() {
process(SampleConstructorAnnotatedBean.class);
@@ -236,6 +246,14 @@ class ReflectiveRuntimeHintsRegistrarTests {
}
@Target({ ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Reflective(TestTypeHintReflectiveProcessor.class)
@interface ReflectiveWithCustomProcessor {
}
interface SampleInterface {
@Reflective
@@ -251,14 +269,24 @@ class ReflectiveRuntimeHintsRegistrarTests {
static class SampleCustomProcessor {
@Reflective(TestReflectiveProcessor.class)
@Reflective(TestMethodHintReflectiveProcessor.class)
public String managed() {
return "test";
}
}
private static class TestReflectiveProcessor extends SimpleReflectiveProcessor {
@Reflective
@ReflectiveWithCustomProcessor
static class SampleMultipleCustomProcessors {
public String managed() {
return "test";
}
}
private static class TestMethodHintReflectiveProcessor extends SimpleReflectiveProcessor {
@Override
protected void registerMethodHint(ReflectionHints hints, Method method) {
@@ -268,4 +296,14 @@ class ReflectiveRuntimeHintsRegistrarTests {
}
private static class TestTypeHintReflectiveProcessor extends SimpleReflectiveProcessor {
@Override
protected void registerTypeHint(ReflectionHints hints, Class<?> type) {
super.registerTypeHint(hints, type);
hints.registerType(type, MemberCategory.INVOKE_DECLARED_METHODS);
}
}
}