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);