16
16
17
17
package org .springframework .aot .hint .support ;
18
18
19
+ import java .lang .annotation .Annotation ;
20
+ import java .lang .reflect .Method ;
21
+ import java .util .LinkedHashSet ;
22
+ import java .util .Set ;
19
23
import java .util .function .Consumer ;
20
24
21
25
import org .springframework .aot .hint .MemberCategory ;
22
26
import org .springframework .aot .hint .RuntimeHints ;
23
27
import org .springframework .aot .hint .TypeHint ;
24
28
import org .springframework .aot .hint .TypeHint .Builder ;
25
- import org .springframework .core .annotation .MergedAnnotation ;
29
+ import org .springframework .core .annotation .AliasFor ;
30
+ import org .springframework .core .annotation .MergedAnnotations ;
26
31
import org .springframework .core .annotation .SynthesizedAnnotation ;
27
32
28
33
/**
@@ -38,24 +43,38 @@ public abstract class RuntimeHintsUtils {
38
43
* that its attributes are visible.
39
44
*/
40
45
public static final Consumer <Builder > ANNOTATION_HINT = hint ->
41
- hint .withMembers (MemberCategory .INVOKE_PUBLIC_METHODS );
46
+ hint .withMembers (MemberCategory .INVOKE_DECLARED_METHODS );
42
47
43
48
/**
44
49
* Register the necessary hints so that the specified annotation is visible
45
- * at runtime.
50
+ * at runtime. If an annotation attributes aliases an attribute of another
51
+ * annotation, it is registered as well and a JDK proxy hints is defined
52
+ * so that the synthesized annotation can be resolved.
46
53
* @param hints the {@link RuntimeHints} instance ot use
47
- * @param annotation the annotation
54
+ * @param annotationType the annotation type
48
55
* @see SynthesizedAnnotation
49
56
*/
50
- public static void registerAnnotation (RuntimeHints hints , MergedAnnotation <?> annotation ) {
51
- hints .reflection ().registerType (annotation .getType (), ANNOTATION_HINT );
52
- MergedAnnotation <?> parentSource = annotation .getMetaSource ();
53
- while (parentSource != null ) {
54
- hints .reflection ().registerType (parentSource .getType (), ANNOTATION_HINT );
55
- parentSource = parentSource .getMetaSource ();
57
+ public static void registerAnnotation (RuntimeHints hints , Class <?> annotationType ) {
58
+ Set <Class <?>> allAnnotations = new LinkedHashSet <>();
59
+ allAnnotations .add (annotationType );
60
+ collectAliasedAnnotations (allAnnotations , annotationType );
61
+ allAnnotations .forEach (annotation -> hints .reflection ().registerType (annotation , ANNOTATION_HINT ));
62
+ if (allAnnotations .size () > 1 ) {
63
+ hints .proxies ().registerJdkProxy (annotationType , SynthesizedAnnotation .class );
56
64
}
57
- if (annotation .synthesize () instanceof SynthesizedAnnotation ) {
58
- hints .proxies ().registerJdkProxy (annotation .getType (), SynthesizedAnnotation .class );
65
+ }
66
+
67
+ private static void collectAliasedAnnotations (Set <Class <?>> types , Class <?> annotationType ) {
68
+ for (Method method : annotationType .getDeclaredMethods ()) {
69
+ MergedAnnotations methodAnnotations = MergedAnnotations .from (method );
70
+ if (methodAnnotations .isPresent (AliasFor .class )) {
71
+ Class <?> aliasedAnnotation = methodAnnotations .get (AliasFor .class ).getClass ("annotation" );
72
+ boolean process = (aliasedAnnotation != Annotation .class && !types .contains (aliasedAnnotation ));
73
+ if (process ) {
74
+ types .add (aliasedAnnotation );
75
+ collectAliasedAnnotations (types , aliasedAnnotation );
76
+ }
77
+ }
59
78
}
60
79
}
61
80
0 commit comments