Refined retrieval of plain annotations through direct presence checks

Shortcut checks apply for hasPlainJavaAnnotationsOnly types as well now.

Closes gh-22685
This commit is contained in:
Juergen Hoeller
2019-03-27 12:56:11 +01:00
parent cb84c56f19
commit c9857702e4
8 changed files with 100 additions and 82 deletions

View File

@@ -200,15 +200,12 @@ public abstract class AnnotatedElementUtils {
* @since 4.2.3
* @see #hasAnnotation(AnnotatedElement, Class)
*/
public static boolean isAnnotated(AnnotatedElement element,Class<? extends Annotation> annotationType) {
// Shortcut: directly present on the element, with no processing needed?
if (AnnotationFilter.PLAIN.matches(annotationType)) {
public static boolean isAnnotated(AnnotatedElement element, Class<? extends Annotation> annotationType) {
// Shortcut: directly present on the element, with no merging needed?
if (AnnotationFilter.PLAIN.matches(annotationType) ||
AnnotationsScanner.hasPlainJavaAnnotationsOnly(element)) {
return element.isAnnotationPresent(annotationType);
}
// Shortcut: no searchable annotations to be found on plain Java classes and core Spring types...
if (AnnotationsScanner.hasPlainJavaAnnotationsOnly(element)) {
return false;
}
// Exhaustive retrieval of merged annotations...
return getAnnotations(element).isPresent(annotationType);
}
@@ -332,13 +329,10 @@ public abstract class AnnotatedElementUtils {
@Nullable
public static <A extends Annotation> A getMergedAnnotation(AnnotatedElement element, Class<A> annotationType) {
// Shortcut: directly present on the element, with no merging needed?
if (AnnotationFilter.PLAIN.matches(annotationType)) {
if (AnnotationFilter.PLAIN.matches(annotationType) ||
AnnotationsScanner.hasPlainJavaAnnotationsOnly(element)) {
return element.getDeclaredAnnotation(annotationType);
}
// Shortcut: no searchable annotations to be found on plain Java classes and core Spring types...
if (AnnotationsScanner.hasPlainJavaAnnotationsOnly(element)) {
return null;
}
// Exhaustive retrieval of merged annotations...
return getAnnotations(element)
.get(annotationType, null, MergedAnnotationSelectors.firstDirectlyDeclared())
@@ -528,14 +522,11 @@ public abstract class AnnotatedElementUtils {
* @see #isAnnotated(AnnotatedElement, Class)
*/
public static boolean hasAnnotation(AnnotatedElement element, Class<? extends Annotation> annotationType) {
// Shortcut: directly present on the element, with no processing needed?
if (AnnotationFilter.PLAIN.matches(annotationType)) {
// Shortcut: directly present on the element, with no merging needed?
if (AnnotationFilter.PLAIN.matches(annotationType) ||
AnnotationsScanner.hasPlainJavaAnnotationsOnly(element)) {
return element.isAnnotationPresent(annotationType);
}
// Shortcut: no searchable annotations to be found on plain Java classes and core Spring types...
if (AnnotationsScanner.hasPlainJavaAnnotationsOnly(element)) {
return false;
}
// Exhaustive retrieval of merged annotations...
return findAnnotations(element).isPresent(annotationType);
}
@@ -633,13 +624,10 @@ public abstract class AnnotatedElementUtils {
@Nullable
public static <A extends Annotation> A findMergedAnnotation(AnnotatedElement element, Class<A> annotationType) {
// Shortcut: directly present on the element, with no merging needed?
if (AnnotationFilter.PLAIN.matches(annotationType)) {
if (AnnotationFilter.PLAIN.matches(annotationType) ||
AnnotationsScanner.hasPlainJavaAnnotationsOnly(element)) {
return element.getDeclaredAnnotation(annotationType);
}
// Shortcut: no searchable annotations to be found on plain Java classes and core Spring types...
if (AnnotationsScanner.hasPlainJavaAnnotationsOnly(element)) {
return null;
}
// Exhaustive retrieval of merged annotations...
return findAnnotations(element)
.get(annotationType, null, MergedAnnotationSelectors.firstDirectlyDeclared())

View File

@@ -28,17 +28,16 @@ import java.lang.annotation.Annotation;
public interface AnnotationFilter {
/**
* {@link AnnotationFilter} that matches annotations is in the
* {@code java.lang.*} or in the
* {@code org.springframework.lang.*} package.
* {@link AnnotationFilter} that matches annotations in the
* {@code java.lang.*} and {@code org.springframework.lang.*} packages.
*/
AnnotationFilter PLAIN = packages("java.lang", "org.springframework.lang");
/**
* {@link AnnotationFilter} that matches annotations in the
* {@code java.lang.*} package.
* {@code java.*}/{@code javax.*} namespaces.
*/
AnnotationFilter JAVA = packages("java.lang");
AnnotationFilter JAVA = packages("java", "javax");
/**
* {@link AnnotationFilter} that never matches and can be used when no

View File

@@ -210,13 +210,10 @@ public abstract class AnnotationUtils {
@Nullable
public static <A extends Annotation> A getAnnotation(AnnotatedElement annotatedElement, Class<A> annotationType) {
// Shortcut: directly present on the element, with no merging needed?
if (AnnotationFilter.PLAIN.matches(annotationType)) {
if (AnnotationFilter.PLAIN.matches(annotationType) ||
AnnotationsScanner.hasPlainJavaAnnotationsOnly(annotatedElement)) {
return annotatedElement.getAnnotation(annotationType);
}
// Shortcut: no searchable annotations to be found on plain Java classes and core Spring types...
if (AnnotationsScanner.hasPlainJavaAnnotationsOnly(annotatedElement)) {
return null;
}
// Exhaustive retrieval of merged annotations...
return MergedAnnotations.from(annotatedElement, SearchStrategy.INHERITED_ANNOTATIONS,
RepeatableContainers.none(), AnnotationFilter.PLAIN)
@@ -483,13 +480,10 @@ public abstract class AnnotationUtils {
return null;
}
// Shortcut: directly present on the element, with no merging needed?
if (AnnotationFilter.PLAIN.matches(annotationType)) {
if (AnnotationFilter.PLAIN.matches(annotationType) ||
AnnotationsScanner.hasPlainJavaAnnotationsOnly(annotatedElement)) {
return annotatedElement.getDeclaredAnnotation(annotationType);
}
// Shortcut: no searchable annotations to be found on plain Java classes and core Spring types...
if (AnnotationsScanner.hasPlainJavaAnnotationsOnly(annotatedElement)) {
return null;
}
// Exhaustive retrieval of merged annotations...
return MergedAnnotations.from(annotatedElement, SearchStrategy.INHERITED_ANNOTATIONS)
.get(annotationType).withNonMergedAttributes()
@@ -517,13 +511,10 @@ public abstract class AnnotationUtils {
return null;
}
// Shortcut: directly present on the element, with no merging needed?
if (AnnotationFilter.PLAIN.matches(annotationType)) {
if (AnnotationFilter.PLAIN.matches(annotationType) ||
AnnotationsScanner.hasPlainJavaAnnotationsOnly(method)) {
return method.getDeclaredAnnotation(annotationType);
}
// Shortcut: no searchable annotations to be found on plain Java classes and core Spring types...
if (AnnotationsScanner.hasPlainJavaAnnotationsOnly(method)) {
return null;
}
// Exhaustive retrieval of merged annotations...
return MergedAnnotations.from(method, SearchStrategy.EXHAUSTIVE)
.get(annotationType).withNonMergedAttributes()
@@ -558,13 +549,10 @@ public abstract class AnnotationUtils {
return null;
}
// Shortcut: directly present on the element, with no merging needed?
if (AnnotationFilter.PLAIN.matches(annotationType)) {
if (AnnotationFilter.PLAIN.matches(annotationType) ||
AnnotationsScanner.hasPlainJavaAnnotationsOnly(clazz)) {
return clazz.getDeclaredAnnotation(annotationType);
}
// Shortcut: no searchable annotations to be found on plain Java classes and core Spring types...
if (AnnotationsScanner.hasPlainJavaAnnotationsOnly(clazz)) {
return null;
}
// Exhaustive retrieval of merged annotations...
return MergedAnnotations.from(clazz, SearchStrategy.EXHAUSTIVE)
.get(annotationType).withNonMergedAttributes()
@@ -710,17 +698,13 @@ public abstract class AnnotationUtils {
return false;
}
// Shortcut: directly present on the element, with no merging needed?
if (AnnotationFilter.PLAIN.matches(annotationType) ||
AnnotationFilter.PLAIN.matches(metaAnnotationType)) {
if (AnnotationFilter.PLAIN.matches(metaAnnotationType) ||
AnnotationsScanner.hasPlainJavaAnnotationsOnly(annotationType)) {
return annotationType.isAnnotationPresent(metaAnnotationType);
}
// Shortcut: no searchable annotations to be found on plain Java classes and core Spring types...
if (AnnotationsScanner.hasPlainJavaAnnotationsOnly(annotationType)) {
return false;
}
// Exhaustive retrieval of merged annotations...
return (MergedAnnotations.from(
annotationType, SearchStrategy.INHERITED_ANNOTATIONS).isPresent(metaAnnotationType));
return MergedAnnotations.from(annotationType, SearchStrategy.INHERITED_ANNOTATIONS,
RepeatableContainers.none(), AnnotationFilter.PLAIN).isPresent(metaAnnotationType);
}
/**

View File

@@ -40,7 +40,7 @@ import org.springframework.lang.Nullable;
*/
final class TypeMappedAnnotations implements MergedAnnotations {
private static final AnnotationFilter FILTER_ALL = annotationType -> true;
private static final AnnotationFilter FILTER_ALL = (annotationType -> true);
private static final MergedAnnotations NONE = new TypeMappedAnnotations(
null, new Annotation[0], RepeatableContainers.none(), FILTER_ALL);
@@ -108,8 +108,8 @@ final class TypeMappedAnnotations implements MergedAnnotations {
}
@Override
public <A extends Annotation> boolean isDirectlyPresent(@Nullable Class<A> annotationType) {
if (annotationType == null || this.annotationFilter.matches(annotationType)) {
public <A extends Annotation> boolean isDirectlyPresent(Class<A> annotationType) {
if (this.annotationFilter.matches(annotationType)) {
return false;
}
return Boolean.TRUE.equals(scan(annotationType,
@@ -176,9 +176,7 @@ final class TypeMappedAnnotations implements MergedAnnotations {
}
@Override
public <A extends Annotation> Stream<MergedAnnotation<A>> stream(
@Nullable Class<A> annotationType) {
public <A extends Annotation> Stream<MergedAnnotation<A>> stream(Class<A> annotationType) {
if (this.annotationFilter == FILTER_ALL) {
return Stream.empty();
}
@@ -186,9 +184,7 @@ final class TypeMappedAnnotations implements MergedAnnotations {
}
@Override
public <A extends Annotation> Stream<MergedAnnotation<A>> stream(
@Nullable String annotationType) {
public <A extends Annotation> Stream<MergedAnnotation<A>> stream(String annotationType) {
if (this.annotationFilter == FILTER_ALL) {
return Stream.empty();
}
@@ -219,8 +215,7 @@ final class TypeMappedAnnotations implements MergedAnnotations {
return spliterator(null);
}
private <A extends Annotation> Spliterator<MergedAnnotation<A>> spliterator(
@Nullable Object annotationType) {
private <A extends Annotation> Spliterator<MergedAnnotation<A>> spliterator(@Nullable Object annotationType) {
return new AggregatesSpliterator<>(annotationType, getAggregates());
}
@@ -248,6 +243,7 @@ final class TypeMappedAnnotations implements MergedAnnotations {
return null;
}
static MergedAnnotations from(@Nullable AnnotatedElement element, SearchStrategy searchStrategy,
RepeatableContainers repeatableContainers, AnnotationFilter annotationFilter) {