Do not inspect meta-annotations on Java annotations
This commit introduces a new isInJavaLangAnnotationPackage(Annotation) method in AnnotationUtils. This method is now used in AnnotationUtils, AnnotatedElementUtils, and MetaAnnotationUtils to ensure that search algorithms do no search for meta-annotations on annotations in the "java.lang.annotation" package. The following are some empirical results from this change: - The number of times that the findAnnotation(Class,Class,Set) method in AnnotationUtils is recursively invoked while executing AnnotationUtilsTests drops from 51 to 29. - The number of times that the process(AnnotatedElement) method in AnnotationUtils.AnnotationCollector is recursively invoked while executing AnnotationUtilsTests.getRepeatableFromMethod() drops from 16 to 2. - The number of times that the doProcess() method in AnnotatedElementUtils is recursively invoked while executing the "getAnnotationAttributes() On MetaCycleAnnotatedClass with missing target meta-annotation" test in AnnotatedElementUtilsTests drops from 23 to 5. - The number of times that the findAnnotationDescriptor(Class,Set,Class) method in MetaAnnotationUtils is recursively invoked while executing the "findAnnotationDescriptor() on MetaCycleAnnotatedClass with missing target meta-annotation" test in MetaAnnotationUtilsTests drops from 16 to 8. Issue: SPR-11483
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
* Copyright 2002-2014 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.
|
||||
@@ -32,6 +32,7 @@ import org.springframework.util.MultiValueMap;
|
||||
*
|
||||
* @author Phillip Webb
|
||||
* @author Juergen Hoeller
|
||||
* @author Sam Brannen
|
||||
* @since 4.0
|
||||
*/
|
||||
public class AnnotatedElementUtils {
|
||||
@@ -159,7 +160,7 @@ public class AnnotatedElementUtils {
|
||||
for (Annotation annotation : element.getAnnotations()) {
|
||||
if (annotation.annotationType().getName().equals(annotationType) || depth > 0) {
|
||||
T result = processor.process(annotation, depth);
|
||||
if (result != null) {
|
||||
if (result != null) {
|
||||
return result;
|
||||
}
|
||||
result = doProcess(annotation.annotationType(), annotationType, processor, visited, depth + 1);
|
||||
@@ -170,10 +171,12 @@ public class AnnotatedElementUtils {
|
||||
}
|
||||
}
|
||||
for (Annotation annotation : element.getAnnotations()) {
|
||||
T result = doProcess(annotation.annotationType(), annotationType, processor, visited, depth);
|
||||
if (result != null) {
|
||||
processor.postProcess(annotation, result);
|
||||
return result;
|
||||
if (!AnnotationUtils.isInJavaLangAnnotationPackage(annotation)) {
|
||||
T result = doProcess(annotation.annotationType(), annotationType, processor, visited, depth);
|
||||
if (result != null) {
|
||||
processor.postProcess(annotation, result);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -289,7 +289,7 @@ public abstract class AnnotationUtils {
|
||||
}
|
||||
}
|
||||
for (Annotation ann : clazz.getAnnotations()) {
|
||||
if (visited.add(ann)) {
|
||||
if (!isInJavaLangAnnotationPackage(ann) && visited.add(ann)) {
|
||||
annotation = findAnnotation(ann.annotationType(), annotationType, visited);
|
||||
if (annotation != null) {
|
||||
return annotation;
|
||||
@@ -422,6 +422,18 @@ public abstract class AnnotationUtils {
|
||||
return (clazz.isAnnotationPresent(annotationType) && !isAnnotationDeclaredLocally(annotationType, clazz));
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the supplied {@link Annotation} is defined in the
|
||||
* {@code java.lang.annotation} package.
|
||||
*
|
||||
* @param annotation the annotation to check; never {@code null}
|
||||
* @return {@code true} if the annotation is in the {@code java.lang.annotation} package
|
||||
*/
|
||||
public static boolean isInJavaLangAnnotationPackage(Annotation annotation) {
|
||||
Assert.notNull(annotation, "Annotation must not be null");
|
||||
return annotation.annotationType().getName().startsWith("java.lang.annotation");
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the given annotation's attributes as a Map, preserving all attribute types
|
||||
* as-is.
|
||||
@@ -631,7 +643,7 @@ public abstract class AnnotationUtils {
|
||||
else if (ObjectUtils.nullSafeEquals(this.containerAnnotationType, annotation.annotationType())) {
|
||||
result.addAll(Arrays.asList(getValue(annotation)));
|
||||
}
|
||||
else {
|
||||
else if (!isInJavaLangAnnotationPackage(annotation)) {
|
||||
process(annotation.annotationType());
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user