2929
3030import org .springframework .core .BridgeMethodResolver ;
3131import org .springframework .util .Assert ;
32+ import org .springframework .util .CollectionUtils ;
3233import org .springframework .util .LinkedMultiValueMap ;
3334import org .springframework .util .MultiValueMap ;
3435
@@ -240,7 +241,6 @@ private static boolean hasMetaAnnotationTypes(AnnotatedElement element, Class<?
240241
241242 return Boolean .TRUE .equals (
242243 searchWithGetSemantics (element , annotationType , annotationName , new SimpleAnnotationProcessor <Boolean >() {
243-
244244 @ Override
245245 public Boolean process (AnnotatedElement annotatedElement , Annotation annotation , int metaDepth ) {
246246 return (metaDepth > 0 ? Boolean .TRUE : CONTINUE );
@@ -270,7 +270,6 @@ public static boolean isAnnotated(AnnotatedElement element, Class<? extends Anno
270270 if (element .isAnnotationPresent (annotationType )) {
271271 return true ;
272272 }
273-
274273 return Boolean .TRUE .equals (searchWithGetSemantics (element , annotationType , null , alwaysTrueAnnotationProcessor ));
275274 }
276275
@@ -615,7 +614,6 @@ public static boolean hasAnnotation(AnnotatedElement element, Class<? extends An
615614 if (element .isAnnotationPresent (annotationType )) {
616615 return true ;
617616 }
618-
619617 return Boolean .TRUE .equals (searchWithFindSemantics (element , annotationType , null , alwaysTrueAnnotationProcessor ));
620618 }
621619
@@ -873,8 +871,8 @@ public static <A extends Annotation> Set<A> findMergedRepeatableAnnotations(Anno
873871 * @param processor the processor to delegate to
874872 * @return the result of the processor (potentially {@code null})
875873 */
876- private static <T > T searchWithGetSemantics (AnnotatedElement element , Class <? extends Annotation > annotationType ,
877- String annotationName , Processor <T > processor ) {
874+ private static <T > T searchWithGetSemantics (AnnotatedElement element ,
875+ Class <? extends Annotation > annotationType , String annotationName , Processor <T > processor ) {
878876
879877 return searchWithGetSemantics (element , annotationType , annotationName , null , processor );
880878 }
@@ -893,12 +891,13 @@ private static <T> T searchWithGetSemantics(AnnotatedElement element, Class<? ex
893891 * @return the result of the processor (potentially {@code null})
894892 * @since 4.3
895893 */
896- private static <T > T searchWithGetSemantics (AnnotatedElement element , Class <? extends Annotation > annotationType ,
897- String annotationName , Class <? extends Annotation > containerType , Processor <T > processor ) {
894+ private static <T > T searchWithGetSemantics (AnnotatedElement element ,
895+ Class <? extends Annotation > annotationType , String annotationName ,
896+ Class <? extends Annotation > containerType , Processor <T > processor ) {
898897
899898 try {
900- return searchWithGetSemantics (element , annotationType , annotationName , containerType , processor ,
901- new HashSet <AnnotatedElement >(), 0 );
899+ return searchWithGetSemantics (element , annotationType , annotationName ,
900+ containerType , processor , new HashSet <AnnotatedElement >(), 0 );
902901 }
903902 catch (Throwable ex ) {
904903 AnnotationUtils .rethrowAnnotationConfigurationException (ex );
@@ -923,8 +922,9 @@ private static <T> T searchWithGetSemantics(AnnotatedElement element, Class<? ex
923922 * @param metaDepth the meta-depth of the annotation
924923 * @return the result of the processor (potentially {@code null})
925924 */
926- private static <T > T searchWithGetSemantics (AnnotatedElement element , Class <? extends Annotation > annotationType ,
927- String annotationName , Class <? extends Annotation > containerType , Processor <T > processor ,
925+ private static <T > T searchWithGetSemantics (AnnotatedElement element ,
926+ Class <? extends Annotation > annotationType , String annotationName ,
927+ Class <? extends Annotation > containerType , Processor <T > processor ,
928928 Set <AnnotatedElement > visited , int metaDepth ) {
929929
930930 Assert .notNull (element , "AnnotatedElement must not be null" );
@@ -939,7 +939,7 @@ private static <T> T searchWithGetSemantics(AnnotatedElement element, Class<? ex
939939 return result ;
940940 }
941941
942- if (element instanceof Class ) { // otherwise getAnnotations doesn't return anything new
942+ if (element instanceof Class ) { // otherwise getAnnotations does not return anything new
943943 List <Annotation > inheritedAnnotations = new ArrayList <Annotation >();
944944 for (Annotation annotation : element .getAnnotations ()) {
945945 if (!declaredAnnotations .contains (annotation )) {
@@ -986,9 +986,9 @@ private static <T> T searchWithGetSemantics(AnnotatedElement element, Class<? ex
986986 * @since 4.2
987987 */
988988 private static <T > T searchWithGetSemanticsInAnnotations (AnnotatedElement element ,
989- List <Annotation > annotations , Class <? extends Annotation > annotationType , String annotationName ,
990- Class <? extends Annotation > containerType , Processor < T > processor , Set < AnnotatedElement > visited ,
991- int metaDepth ) {
989+ List <Annotation > annotations , Class <? extends Annotation > annotationType ,
990+ String annotationName , Class <? extends Annotation > containerType ,
991+ Processor < T > processor , Set < AnnotatedElement > visited , int metaDepth ) {
992992
993993 // Search in annotations
994994 for (Annotation annotation : annotations ) {
@@ -1054,7 +1054,8 @@ else if (currentAnnotationType == containerType) {
10541054 * @return the result of the processor (potentially {@code null})
10551055 * @since 4.2
10561056 */
1057- private static <T > T searchWithFindSemantics (AnnotatedElement element , Class <? extends Annotation > annotationType ,
1057+ private static <T > T searchWithFindSemantics (AnnotatedElement element ,
1058+ Class <? extends Annotation > annotationType ,
10581059 String annotationName , Processor <T > processor ) {
10591060
10601061 return searchWithFindSemantics (element , annotationType , annotationName , null , processor );
@@ -1074,17 +1075,18 @@ private static <T> T searchWithFindSemantics(AnnotatedElement element, Class<? e
10741075 * @return the result of the processor (potentially {@code null})
10751076 * @since 4.3
10761077 */
1077- private static <T > T searchWithFindSemantics (AnnotatedElement element , Class <? extends Annotation > annotationType ,
1078- String annotationName , Class <? extends Annotation > containerType , Processor <T > processor ) {
1078+ private static <T > T searchWithFindSemantics (AnnotatedElement element ,
1079+ Class <? extends Annotation > annotationType , String annotationName ,
1080+ Class <? extends Annotation > containerType , Processor <T > processor ) {
10791081
10801082 if (containerType != null && !processor .aggregates ()) {
10811083 throw new IllegalArgumentException (
10821084 "Searches for repeatable annotations must supply an aggregating Processor" );
10831085 }
10841086
10851087 try {
1086- return searchWithFindSemantics (
1087- element , annotationType , annotationName , containerType , processor , new HashSet <AnnotatedElement >(), 0 );
1088+ return searchWithFindSemantics (element , annotationType , annotationName ,
1089+ containerType , processor , new HashSet <AnnotatedElement >(), 0 );
10881090 }
10891091 catch (Throwable ex ) {
10901092 AnnotationUtils .rethrowAnnotationConfigurationException (ex );
@@ -1120,79 +1122,86 @@ private static <T> T searchWithFindSemantics(AnnotatedElement element, Class<? e
11201122 try {
11211123 // Locally declared annotations (ignoring @Inherited)
11221124 Annotation [] annotations = element .getDeclaredAnnotations ();
1123- List <T > aggregatedResults = (processor .aggregates () ? new ArrayList <T >() : null );
1124-
1125- // Search in local annotations
1126- for (Annotation annotation : annotations ) {
1127- Class <? extends Annotation > currentAnnotationType = annotation .annotationType ();
1128- if (!AnnotationUtils .isInJavaLangAnnotationPackage (currentAnnotationType )) {
1129- if (currentAnnotationType == annotationType ||
1130- currentAnnotationType .getName ().equals (annotationName ) ||
1131- processor .alwaysProcesses ()) {
1132- T result = processor .process (element , annotation , metaDepth );
1133- if (result != null ) {
1134- if (processor .aggregates () && metaDepth == 0 ) {
1135- aggregatedResults .add (result );
1136- }
1137- else {
1138- return result ;
1125+ if (annotations .length > 0 ) {
1126+ List <T > aggregatedResults = (processor .aggregates () ? new ArrayList <T >() : null );
1127+
1128+ // Search in local annotations
1129+ for (Annotation annotation : annotations ) {
1130+ Class <? extends Annotation > currentAnnotationType = annotation .annotationType ();
1131+ if (!AnnotationUtils .isInJavaLangAnnotationPackage (currentAnnotationType )) {
1132+ if (currentAnnotationType == annotationType ||
1133+ currentAnnotationType .getName ().equals (annotationName ) ||
1134+ processor .alwaysProcesses ()) {
1135+ T result = processor .process (element , annotation , metaDepth );
1136+ if (result != null ) {
1137+ if (aggregatedResults != null && metaDepth == 0 ) {
1138+ aggregatedResults .add (result );
1139+ }
1140+ else {
1141+ return result ;
1142+ }
11391143 }
11401144 }
1141- }
1142- // Repeatable annotations in container?
1143- else if ( currentAnnotationType == containerType ) {
1144- for ( Annotation contained : getRawAnnotationsFromContainer (element , annotation )) {
1145- T result = processor . process ( element , contained , metaDepth );
1146- if ( result != null ) {
1147- // No need to post-process since repeatable annotations within a
1148- // container cannot be composed annotations.
1149- aggregatedResults . add ( result );
1145+ // Repeatable annotations in container?
1146+ else if ( currentAnnotationType == containerType ) {
1147+ for ( Annotation contained : getRawAnnotationsFromContainer ( element , annotation ) ) {
1148+ T result = processor . process (element , contained , metaDepth );
1149+ if ( aggregatedResults != null && result != null ) {
1150+ // No need to post-process since repeatable annotations within a
1151+ // container cannot be composed annotations.
1152+ aggregatedResults . add ( result );
1153+ }
11501154 }
11511155 }
11521156 }
11531157 }
1154- }
11551158
1156- // Search in meta annotations on local annotations
1157- for (Annotation annotation : annotations ) {
1158- Class <? extends Annotation > currentAnnotationType = annotation .annotationType ();
1159- if (!AnnotationUtils .isInJavaLangAnnotationPackage (currentAnnotationType )) {
1160- T result = searchWithFindSemantics (currentAnnotationType , annotationType , annotationName ,
1161- containerType , processor , visited , metaDepth + 1 );
1162- if (result != null ) {
1163- processor .postProcess (currentAnnotationType , annotation , result );
1164- if (processor .aggregates () && metaDepth == 0 ) {
1165- aggregatedResults .add (result );
1166- }
1167- else {
1168- return result ;
1159+ // Recursively search in meta-annotations
1160+ for (Annotation annotation : annotations ) {
1161+ Class <? extends Annotation > currentAnnotationType = annotation .annotationType ();
1162+ if (!AnnotationUtils .isInJavaLangAnnotationPackage (currentAnnotationType )) {
1163+ T result = searchWithFindSemantics (currentAnnotationType , annotationType , annotationName ,
1164+ containerType , processor , visited , metaDepth + 1 );
1165+ if (result != null ) {
1166+ processor .postProcess (currentAnnotationType , annotation , result );
1167+ if (aggregatedResults != null && metaDepth == 0 ) {
1168+ aggregatedResults .add (result );
1169+ }
1170+ else {
1171+ return result ;
1172+ }
11691173 }
11701174 }
11711175 }
1172- }
11731176
1174- if (processor .aggregates ()) {
1175- // Prepend to support top-down ordering within class hierarchies
1176- processor .getAggregatedResults ().addAll (0 , aggregatedResults );
1177+ if (!CollectionUtils .isEmpty (aggregatedResults )) {
1178+ // Prepend to support top-down ordering within class hierarchies
1179+ processor .getAggregatedResults ().addAll (0 , aggregatedResults );
1180+ }
11771181 }
11781182
11791183 if (element instanceof Method ) {
11801184 Method method = (Method ) element ;
1185+ T result ;
11811186
11821187 // Search on possibly bridged method
11831188 Method resolvedMethod = BridgeMethodResolver .findBridgedMethod (method );
1184- T result = searchWithFindSemantics (resolvedMethod , annotationType , annotationName , containerType ,
1185- processor , visited , metaDepth );
1186- if (result != null ) {
1187- return result ;
1189+ if (resolvedMethod != method ) {
1190+ result = searchWithFindSemantics (resolvedMethod , annotationType , annotationName ,
1191+ containerType , processor , visited , metaDepth );
1192+ if (result != null ) {
1193+ return result ;
1194+ }
11881195 }
11891196
11901197 // Search on methods in interfaces declared locally
11911198 Class <?>[] ifcs = method .getDeclaringClass ().getInterfaces ();
1192- result = searchOnInterfaces (method , annotationType , annotationName , containerType , processor ,
1193- visited , metaDepth , ifcs );
1194- if (result != null ) {
1195- return result ;
1199+ if (ifcs .length > 0 ) {
1200+ result = searchOnInterfaces (method , annotationType , annotationName ,
1201+ containerType , processor , visited , metaDepth , ifcs );
1202+ if (result != null ) {
1203+ return result ;
1204+ }
11961205 }
11971206
11981207 // Search on methods in class hierarchy and interface hierarchy
@@ -1202,7 +1211,6 @@ else if (currentAnnotationType == containerType) {
12021211 if (clazz == null || Object .class == clazz ) {
12031212 break ;
12041213 }
1205-
12061214 try {
12071215 Method equivalentMethod = clazz .getDeclaredMethod (method .getName (), method .getParameterTypes ());
12081216 Method resolvedEquivalentMethod = BridgeMethodResolver .findBridgedMethod (equivalentMethod );
@@ -1215,10 +1223,9 @@ else if (currentAnnotationType == containerType) {
12151223 catch (NoSuchMethodException ex ) {
12161224 // No equivalent method found
12171225 }
1218-
12191226 // Search on interfaces declared on superclass
1220- result = searchOnInterfaces (method , annotationType , annotationName , containerType , processor ,
1221- visited , metaDepth , clazz .getInterfaces ());
1227+ result = searchOnInterfaces (method , annotationType , annotationName ,
1228+ containerType , processor , visited , metaDepth , clazz .getInterfaces ());
12221229 if (result != null ) {
12231230 return result ;
12241231 }
@@ -1229,8 +1236,8 @@ else if (element instanceof Class) {
12291236
12301237 // Search on interfaces
12311238 for (Class <?> ifc : clazz .getInterfaces ()) {
1232- T result = searchWithFindSemantics (ifc , annotationType , annotationName , containerType ,
1233- processor , visited , metaDepth );
1239+ T result = searchWithFindSemantics (ifc , annotationType , annotationName ,
1240+ containerType , processor , visited , metaDepth );
12341241 if (result != null ) {
12351242 return result ;
12361243 }
@@ -1239,8 +1246,8 @@ else if (element instanceof Class) {
12391246 // Search on superclass
12401247 Class <?> superclass = clazz .getSuperclass ();
12411248 if (superclass != null && Object .class != superclass ) {
1242- T result = searchWithFindSemantics (superclass , annotationType , annotationName , containerType ,
1243- processor , visited , metaDepth );
1249+ T result = searchWithFindSemantics (superclass , annotationType , annotationName ,
1250+ containerType , processor , visited , metaDepth );
12441251 if (result != null ) {
12451252 return result ;
12461253 }
0 commit comments