diff --git a/spring-core/src/main/java/org/springframework/core/annotation/AnnotatedElementUtils.java b/spring-core/src/main/java/org/springframework/core/annotation/AnnotatedElementUtils.java index 1d076695d67..2ace4ac0486 100644 --- a/spring-core/src/main/java/org/springframework/core/annotation/AnnotatedElementUtils.java +++ b/spring-core/src/main/java/org/springframework/core/annotation/AnnotatedElementUtils.java @@ -445,10 +445,10 @@ public class AnnotatedElementUtils { * single annotation and within annotation hierarchies. *

This method follows get semantics as described in the * {@linkplain AnnotatedElementUtils class-level javadoc}. - * @param element the annotated element; never {@code null} - * @param annotationType the annotation type to find; never {@code null} - * @return the set of all merged, synthesized {@code Annotations} found, or an empty - * set if none were found + * @param element the annotated element (never {@code null}) + * @param annotationType the annotation type to find (never {@code null}) + * @return the set of all merged, synthesized {@code Annotations} found, + * or an empty set if none were found * @since 4.3 * @see #getMergedAnnotation(AnnotatedElement, Class) * @see #getAllAnnotationAttributes(AnnotatedElement, String) @@ -478,10 +478,10 @@ public class AnnotatedElementUtils { * single annotation and within annotation hierarchies. *

This method follows get semantics as described in the * {@linkplain AnnotatedElementUtils class-level javadoc}. - * @param element the annotated element; never {@code null} - * @param annotationType the annotation type to find; never {@code null} - * @return the set of all merged repeatable {@code Annotations} found, or an empty - * set if none were found + * @param element the annotated element (never {@code null}) + * @param annotationType the annotation type to find (never {@code null}) + * @return the set of all merged repeatable {@code Annotations} found, + * or an empty set if none were found * @since 4.3 * @see #getMergedAnnotation(AnnotatedElement, Class) * @see #getAllMergedAnnotations(AnnotatedElement, Class) @@ -506,13 +506,13 @@ public class AnnotatedElementUtils { * single annotation and within annotation hierarchies. *

This method follows get semantics as described in the * {@linkplain AnnotatedElementUtils class-level javadoc}. - * @param element the annotated element; never {@code null} - * @param annotationType the annotation type to find; never {@code null} + * @param element the annotated element (never {@code null}) + * @param annotationType the annotation type to find (never {@code null}) * @param containerType the type of the container that holds the annotations; * may be {@code null} if the container type should be looked up via * {@link java.lang.annotation.Repeatable} - * @return the set of all merged repeatable {@code Annotations} found, or an empty - * set if none were found + * @return the set of all merged repeatable {@code Annotations} found, + * or an empty set if none were found * @since 4.3 * @see #getMergedAnnotation(AnnotatedElement, Class) * @see #getAllMergedAnnotations(AnnotatedElement, Class) @@ -771,10 +771,10 @@ public class AnnotatedElementUtils { * single annotation and within annotation hierarchies. *

This method follows find semantics as described in the * {@linkplain AnnotatedElementUtils class-level javadoc}. - * @param element the annotated element; never {@code null} - * @param annotationType the annotation type to find; never {@code null} - * @return the set of all merged, synthesized {@code Annotations} found, or an empty - * set if none were found + * @param element the annotated element (never {@code null}) + * @param annotationType the annotation type to find (never {@code null}) + * @return the set of all merged, synthesized {@code Annotations} found, + * or an empty set if none were found * @since 4.3 * @see #findMergedAnnotation(AnnotatedElement, Class) * @see #getAllMergedAnnotations(AnnotatedElement, Class) @@ -803,10 +803,10 @@ public class AnnotatedElementUtils { * single annotation and within annotation hierarchies. *

This method follows find semantics as described in the * {@linkplain AnnotatedElementUtils class-level javadoc}. - * @param element the annotated element; never {@code null} - * @param annotationType the annotation type to find; never {@code null} - * @return the set of all merged repeatable {@code Annotations} found, or an empty - * set if none were found + * @param element the annotated element (never {@code null}) + * @param annotationType the annotation type to find (never {@code null}) + * @return the set of all merged repeatable {@code Annotations} found, + * or an empty set if none were found * @since 4.3 * @see #findMergedAnnotation(AnnotatedElement, Class) * @see #findAllMergedAnnotations(AnnotatedElement, Class) @@ -831,13 +831,13 @@ public class AnnotatedElementUtils { * single annotation and within annotation hierarchies. *

This method follows find semantics as described in the * {@linkplain AnnotatedElementUtils class-level javadoc}. - * @param element the annotated element; never {@code null} - * @param annotationType the annotation type to find; never {@code null} + * @param element the annotated element (never {@code null}) + * @param annotationType the annotation type to find (never {@code null}) * @param containerType the type of the container that holds the annotations; * may be {@code null} if the container type should be looked up via * {@link java.lang.annotation.Repeatable} - * @return the set of all merged repeatable {@code Annotations} found, or an empty - * set if none were found + * @return the set of all merged repeatable {@code Annotations} found, + * or an empty set if none were found * @since 4.3 * @see #findMergedAnnotation(AnnotatedElement, Class) * @see #findAllMergedAnnotations(AnnotatedElement, Class) @@ -994,9 +994,10 @@ public class AnnotatedElementUtils { // Search in annotations for (Annotation annotation : annotations) { - if (!AnnotationUtils.isInJavaLangAnnotationPackage(annotation)) { - if (annotation.annotationType() == annotationType || - annotation.annotationType().getName().equals(annotationName) || + Class currentAnnotationType = annotation.annotationType(); + if (!AnnotationUtils.isInJavaLangAnnotationPackage(currentAnnotationType)) { + if (currentAnnotationType == annotationType || + currentAnnotationType.getName().equals(annotationName) || processor.alwaysProcesses()) { T result = processor.process(element, annotation, metaDepth); if (result != null) { @@ -1009,7 +1010,7 @@ public class AnnotatedElementUtils { } } // Repeatable annotations in container? - else if (annotation.annotationType() == containerType) { + else if (currentAnnotationType == containerType) { for (Annotation contained : getRawAnnotationsFromContainer(element, annotation)) { T result = processor.process(element, contained, metaDepth); if (result != null) { @@ -1024,8 +1025,9 @@ public class AnnotatedElementUtils { // Recursively search in meta-annotations for (Annotation annotation : annotations) { - if (!AnnotationUtils.isInJavaLangAnnotationPackage(annotation)) { - T result = searchWithGetSemantics(annotation.annotationType(), annotationType, + Class currentAnnotationType = annotation.annotationType(); + if (!AnnotationUtils.isInJavaLangAnnotationPackage(currentAnnotationType)) { + T result = searchWithGetSemantics(currentAnnotationType, annotationType, annotationName, containerType, processor, visited, metaDepth + 1); if (result != null) { processor.postProcess(element, annotation, result); @@ -1098,7 +1100,7 @@ public class AnnotatedElementUtils { * have already been visited. *

The {@code metaDepth} parameter is explained in the * {@link Processor#process process()} method of the {@link Processor} API. - * @param element the annotated element; never {@code null} + * @param element the annotated element (never {@code null}) * @param annotationType the annotation type to find * @param annotationName the fully qualified class name of the annotation * type to find (as an alternative to {@code annotationType}) @@ -1124,11 +1126,11 @@ public class AnnotatedElementUtils { // Search in local annotations for (Annotation annotation : annotations) { - if (!AnnotationUtils.isInJavaLangAnnotationPackage(annotation)) { - if (annotation.annotationType() == annotationType - || annotation.annotationType().getName().equals(annotationName) - || processor.alwaysProcesses()) { - + Class currentAnnotationType = annotation.annotationType(); + if (!AnnotationUtils.isInJavaLangAnnotationPackage(currentAnnotationType)) { + if (currentAnnotationType == annotationType || + currentAnnotationType.getName().equals(annotationName) || + processor.alwaysProcesses()) { T result = processor.process(element, annotation, metaDepth); if (result != null) { if (processor.aggregates() && metaDepth == 0) { @@ -1140,7 +1142,7 @@ public class AnnotatedElementUtils { } } // Repeatable annotations in container? - else if (annotation.annotationType() == containerType) { + else if (currentAnnotationType == containerType) { for (Annotation contained : getRawAnnotationsFromContainer(element, annotation)) { T result = processor.process(element, contained, metaDepth); if (result != null) { @@ -1155,11 +1157,12 @@ public class AnnotatedElementUtils { // Search in meta annotations on local annotations for (Annotation annotation : annotations) { - if (!AnnotationUtils.isInJavaLangAnnotationPackage(annotation)) { - T result = searchWithFindSemantics(annotation.annotationType(), annotationType, annotationName, + Class currentAnnotationType = annotation.annotationType(); + if (!AnnotationUtils.isInJavaLangAnnotationPackage(currentAnnotationType)) { + T result = searchWithFindSemantics(currentAnnotationType, annotationType, annotationName, containerType, processor, visited, metaDepth + 1); if (result != null) { - processor.postProcess(annotation.annotationType(), annotation, result); + processor.postProcess(currentAnnotationType, annotation, result); if (processor.aggregates() && metaDepth == 0) { aggregatedResults.add(result); } @@ -1299,7 +1302,7 @@ public class AnnotatedElementUtils { * Resolve the container type for the supplied repeatable {@code annotationType}. *

Delegates to {@link AnnotationUtils#resolveContainerAnnotationType(Class)}. * @param annotationType the annotation type to resolve the container for - * @return the container type; never {@code null} + * @return the container type (never {@code null}) * @throws IllegalArgumentException if the container type cannot be resolved * @since 4.3 */ @@ -1450,8 +1453,8 @@ public class AnnotatedElementUtils { * responsible for asking this processor if it {@link #aggregates} results * and then adding the post-processed results to the list returned by this * method. - * @return the list of results aggregated by this processor; never - * {@code null} unless {@link #aggregates} returns {@code false} + * @return the list of results aggregated by this processor + * (never {@code null} unless {@link #aggregates} returns {@code false}) * @see #aggregates * @since 4.3 */ diff --git a/spring-core/src/main/java/org/springframework/core/annotation/AnnotationUtils.java b/spring-core/src/main/java/org/springframework/core/annotation/AnnotationUtils.java index 76b135a65ed..1d35aac4f2e 100644 --- a/spring-core/src/main/java/org/springframework/core/annotation/AnnotationUtils.java +++ b/spring-core/src/main/java/org/springframework/core/annotation/AnnotationUtils.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -63,7 +63,7 @@ import org.springframework.util.StringUtils; *

Terminology

* The terms directly present, indirectly present, and * present have the same meanings as defined in the class-level - * Javadoc for {@link AnnotatedElement} (in Java 8). + * javadoc for {@link AnnotatedElement} (in Java 8). * *

An annotation is meta-present on an element if the annotation * is declared as a meta-annotation on some other annotation which is @@ -855,7 +855,7 @@ public abstract class AnnotationUtils { *

If the supplied {@code clazz} is an interface, only the interface * itself will be checked. In accordance with standard meta-annotation * semantics in Java, the inheritance hierarchy for interfaces will not - * be traversed. See the {@linkplain java.lang.annotation.Inherited Javadoc} + * be traversed. See the {@linkplain java.lang.annotation.Inherited javadoc} * for the {@code @Inherited} meta-annotation for further details regarding * annotation inheritance. * @param annotationType the annotation type to look for @@ -907,13 +907,24 @@ public abstract class AnnotationUtils { * @return {@code true} if the annotation is in the {@code java.lang.annotation} package */ public static boolean isInJavaLangAnnotationPackage(Annotation annotation) { - return (annotation != null && isInJavaLangAnnotationPackage(annotation.annotationType().getName())); + return (annotation != null && isInJavaLangAnnotationPackage(annotation.annotationType())); } /** * Determine if the {@link Annotation} with the supplied name is defined * in the core JDK {@code java.lang.annotation} package. - * @param annotationType the name of the annotation type to check (never {@code null} or empty) + * @param annotationType the annotation type to check + * @return {@code true} if the annotation is in the {@code java.lang.annotation} package + * @since 4.3.8 + */ + static boolean isInJavaLangAnnotationPackage(Class annotationType) { + return (annotationType != null && isInJavaLangAnnotationPackage(annotationType.getName())); + } + + /** + * Determine if the {@link Annotation} with the supplied name is defined + * in the core JDK {@code java.lang.annotation} package. + * @param annotationType the name of the annotation type to check * @return {@code true} if the annotation is in the {@code java.lang.annotation} package * @since 4.2 */ @@ -1558,8 +1569,8 @@ public abstract class AnnotationUtils { * {@linkplain #synthesizeAnnotation(Map, Class, AnnotatedElement) * synthesized} versions of the maps from the input array. * @param maps the array of maps of annotation attributes to synthesize - * @param annotationType the type of annotations to synthesize; never - * {@code null} + * @param annotationType the type of annotations to synthesize + * (never {@code null}) * @return a new array of synthesized annotations, or {@code null} if * the supplied array is {@code null} * @throws AnnotationConfigurationException if invalid configuration of @@ -1707,8 +1718,8 @@ public abstract class AnnotationUtils { /** * Get the name of the overridden attribute configured via * {@link AliasFor @AliasFor} for the supplied annotation {@code attribute}. - * @param attribute the attribute from which to retrieve the override; - * never {@code null} + * @param attribute the attribute from which to retrieve the override + * (never {@code null}) * @param metaAnnotationType the type of meta-annotation in which the * overridden attribute is allowed to be declared * @return the name of the overridden attribute, or {@code null} if not @@ -1735,8 +1746,8 @@ public abstract class AnnotationUtils { * match Java's requirements for annotation attributes. *

All methods in the returned list will be * {@linkplain ReflectionUtils#makeAccessible(Method) made accessible}. - * @param annotationType the type in which to search for attribute methods; - * never {@code null} + * @param annotationType the type in which to search for attribute methods + * (never {@code null}) * @return all annotation attribute methods in the specified annotation * type (never {@code null}, though potentially empty) * @since 4.2 diff --git a/spring-core/src/main/java/org/springframework/core/type/classreading/AnnotationAttributesReadingVisitor.java b/spring-core/src/main/java/org/springframework/core/type/classreading/AnnotationAttributesReadingVisitor.java index 69f7faba075..6788b197ada 100644 --- a/spring-core/src/main/java/org/springframework/core/type/classreading/AnnotationAttributesReadingVisitor.java +++ b/spring-core/src/main/java/org/springframework/core/type/classreading/AnnotationAttributesReadingVisitor.java @@ -92,17 +92,18 @@ final class AnnotationAttributesReadingVisitor extends RecursiveAnnotationAttrib } private void recursivelyCollectMetaAnnotations(Set visited, Annotation annotation) { - if (!AnnotationUtils.isInJavaLangAnnotationPackage(annotation) && visited.add(annotation)) { + Class annotationType = annotation.annotationType(); + String annotationName = annotationType.getName(); + if (!AnnotationUtils.isInJavaLangAnnotationPackage(annotationName) && visited.add(annotation)) { try { // Only do attribute scanning for public annotations; we'd run into // IllegalAccessExceptions otherwise, and we don't want to mess with // accessibility in a SecurityManager environment. - if (Modifier.isPublic(annotation.annotationType().getModifiers())) { - String annotationName = annotation.annotationType().getName(); + if (Modifier.isPublic(annotationType.getModifiers())) { this.attributesMap.add(annotationName, AnnotationUtils.getAnnotationAttributes(annotation, false, true)); } - for (Annotation metaMetaAnnotation : annotation.annotationType().getAnnotations()) { + for (Annotation metaMetaAnnotation : annotationType.getAnnotations()) { recursivelyCollectMetaAnnotations(visited, metaMetaAnnotation); } } diff --git a/spring-test/src/main/java/org/springframework/test/util/MetaAnnotationUtils.java b/spring-test/src/main/java/org/springframework/test/util/MetaAnnotationUtils.java index 9c203d743e2..a740631282a 100644 --- a/spring-test/src/main/java/org/springframework/test/util/MetaAnnotationUtils.java +++ b/spring-test/src/main/java/org/springframework/test/util/MetaAnnotationUtils.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -110,13 +110,13 @@ public abstract class MetaAnnotationUtils { } // Declared on a composed annotation (i.e., as a meta-annotation)? - for (Annotation composedAnnotation : clazz.getDeclaredAnnotations()) { - if (!AnnotationUtils.isInJavaLangAnnotationPackage(composedAnnotation) && visited.add(composedAnnotation)) { - AnnotationDescriptor descriptor = findAnnotationDescriptor( - composedAnnotation.annotationType(), visited, annotationType); + for (Annotation composedAnn : clazz.getDeclaredAnnotations()) { + Class composedType = composedAnn.annotationType(); + if (!AnnotationUtils.isInJavaLangAnnotationPackage(composedType.getName()) && visited.add(composedAnn)) { + AnnotationDescriptor descriptor = findAnnotationDescriptor(composedType, visited, annotationType); if (descriptor != null) { return new AnnotationDescriptor( - clazz, descriptor.getDeclaringClass(), composedAnnotation, descriptor.getAnnotation()); + clazz, descriptor.getDeclaringClass(), composedAnn, descriptor.getAnnotation()); } } } @@ -126,7 +126,7 @@ public abstract class MetaAnnotationUtils { AnnotationDescriptor descriptor = findAnnotationDescriptor(ifc, visited, annotationType); if (descriptor != null) { return new AnnotationDescriptor(clazz, descriptor.getDeclaringClass(), - descriptor.getComposedAnnotation(), descriptor.getAnnotation()); + descriptor.getComposedAnnotation(), descriptor.getAnnotation()); } } @@ -203,8 +203,8 @@ public abstract class MetaAnnotationUtils { UntypedAnnotationDescriptor descriptor = findAnnotationDescriptorForTypes( composedAnnotation.annotationType(), visited, annotationTypes); if (descriptor != null) { - return new UntypedAnnotationDescriptor(clazz, descriptor.getDeclaringClass(), composedAnnotation, - descriptor.getAnnotation()); + return new UntypedAnnotationDescriptor(clazz, descriptor.getDeclaringClass(), + composedAnnotation, descriptor.getAnnotation()); } } } @@ -214,7 +214,7 @@ public abstract class MetaAnnotationUtils { UntypedAnnotationDescriptor descriptor = findAnnotationDescriptorForTypes(ifc, visited, annotationTypes); if (descriptor != null) { return new UntypedAnnotationDescriptor(clazz, descriptor.getDeclaringClass(), - descriptor.getComposedAnnotation(), descriptor.getAnnotation()); + descriptor.getComposedAnnotation(), descriptor.getAnnotation()); } } @@ -295,8 +295,8 @@ public abstract class MetaAnnotationUtils { public AnnotationDescriptor(Class rootDeclaringClass, Class declaringClass, Annotation composedAnnotation, T annotation) { - Assert.notNull(rootDeclaringClass, "rootDeclaringClass must not be null"); - Assert.notNull(annotation, "annotation must not be null"); + Assert.notNull(rootDeclaringClass, "'rootDeclaringClass' must not be null"); + Assert.notNull(annotation, "Annotation must not be null"); this.rootDeclaringClass = rootDeclaringClass; this.declaringClass = declaringClass; this.composedAnnotation = composedAnnotation;