From 916a871fbcc2b21c3f456613c28d498cb3f5750a Mon Sep 17 00:00:00 2001 From: Stephane Nicoll Date: Fri, 29 Jul 2022 15:38:09 +0200 Subject: [PATCH] Add dedicated hint support for composable annotations This commit adds a dedicated method for annotations that are used as meta-annotation when the composed annotation does not require to be visible at runtime. Closes gh-28887 --- .../aot/hint/support/RuntimeHintsUtils.java | 20 ++++++++++++++++++- .../hint/support/RuntimeHintsUtilsTests.java | 9 +++++++++ 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/spring-core/src/main/java/org/springframework/aot/hint/support/RuntimeHintsUtils.java b/spring-core/src/main/java/org/springframework/aot/hint/support/RuntimeHintsUtils.java index a859807883..6976b39f04 100644 --- a/spring-core/src/main/java/org/springframework/aot/hint/support/RuntimeHintsUtils.java +++ b/spring-core/src/main/java/org/springframework/aot/hint/support/RuntimeHintsUtils.java @@ -57,6 +57,24 @@ public abstract class RuntimeHintsUtils { * @see SynthesizedAnnotation */ public static void registerAnnotation(RuntimeHints hints, Class annotationType) { + registerAnnotation(hints, annotationType, false); + } + + /** + * Register the necessary hints so that the specified composable + * annotation is visible at runtime. Use this method rather than the regular + * {@link #registerAnnotation(RuntimeHints, Class)} when the specified + * annotation is meta-annotated, but the meta-annotated annotations do not + * need to be visible. + * @param hints the {@link RuntimeHints} instance to use + * @param annotationType the composable annotation type + * @see #registerAnnotation(RuntimeHints, Class) + */ + public static void registerComposableAnnotation(RuntimeHints hints, Class annotationType) { + registerAnnotation(hints, annotationType, true); + } + + private static void registerAnnotation(RuntimeHints hints, Class annotationType, boolean withProxy) { hints.reflection().registerType(annotationType, ANNOTATION_HINT); Set> allAnnotations = new LinkedHashSet<>(); collectAliasedAnnotations(new HashSet<>(), allAnnotations, annotationType); @@ -64,7 +82,7 @@ public abstract class RuntimeHintsUtils { hints.reflection().registerType(annotation, ANNOTATION_HINT); hints.proxies().registerJdkProxy(annotation, SynthesizedAnnotation.class); }); - if (!allAnnotations.isEmpty()) { + if (!allAnnotations.isEmpty() || withProxy) { hints.proxies().registerJdkProxy(annotationType, SynthesizedAnnotation.class); } } diff --git a/spring-core/src/test/java/org/springframework/aot/hint/support/RuntimeHintsUtilsTests.java b/spring-core/src/test/java/org/springframework/aot/hint/support/RuntimeHintsUtilsTests.java index 385a2c951b..8d57da8762 100644 --- a/spring-core/src/test/java/org/springframework/aot/hint/support/RuntimeHintsUtilsTests.java +++ b/spring-core/src/test/java/org/springframework/aot/hint/support/RuntimeHintsUtilsTests.java @@ -50,6 +50,15 @@ class RuntimeHintsUtilsTests { assertThat(this.hints.proxies().jdkProxies()).isEmpty(); } + @Test + void registerComposableAnnotationType() { + RuntimeHintsUtils.registerComposableAnnotation(this.hints, SampleInvoker.class); + assertThat(this.hints.reflection().typeHints()).singleElement() + .satisfies(annotationHint(SampleInvoker.class)); + assertThat(this.hints.proxies().jdkProxies()).singleElement() + .satisfies(annotationProxy(SampleInvoker.class)); + } + @Test void registerAnnotationTypeWithLocalUseOfAliasForRegistersProxy() { RuntimeHintsUtils.registerAnnotation(this.hints, LocalMapping.class);