Browse Source

Streamline AnnotationFilter usage with the MergedAnnotations API

MergedAnnotations provides 'from' variants with RepeatableContainers but without AnnotationFilter argument now, avoiding the need to refer to AnnotationFilter.PLAIN as a default at call sites.
pull/23582/head
Juergen Hoeller 5 years ago
parent
commit
3bc27e8d14
  1. 5
      spring-beans/src/main/java/org/springframework/beans/factory/annotation/AutowiredAnnotationBeanPostProcessor.java
  2. 3
      spring-context/src/main/java/org/springframework/jmx/export/annotation/AnnotationJmxAttributeSource.java
  3. 12
      spring-core/src/main/java/org/springframework/core/annotation/AnnotatedElementUtils.java
  4. 33
      spring-core/src/main/java/org/springframework/core/annotation/AnnotationFilter.java
  5. 28
      spring-core/src/main/java/org/springframework/core/annotation/AnnotationUtils.java
  6. 43
      spring-core/src/main/java/org/springframework/core/annotation/MergedAnnotations.java
  7. 21
      spring-core/src/main/java/org/springframework/core/annotation/TypeMappedAnnotations.java
  8. 7
      spring-core/src/main/java/org/springframework/core/type/StandardMethodMetadata.java

5
spring-beans/src/main/java/org/springframework/beans/factory/annotation/AutowiredAnnotationBeanPostProcessor.java

@ -62,7 +62,6 @@ import org.springframework.core.annotation.AnnotationAttributes; @@ -62,7 +62,6 @@ import org.springframework.core.annotation.AnnotationAttributes;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.core.annotation.MergedAnnotation;
import org.springframework.core.annotation.MergedAnnotations;
import org.springframework.core.annotation.MergedAnnotations.SearchStrategy;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
@ -515,7 +514,7 @@ public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBean @@ -515,7 +514,7 @@ public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBean
@Nullable
private MergedAnnotation<?> findAutowiredAnnotation(AccessibleObject ao) {
MergedAnnotations annotations = MergedAnnotations.from(ao, SearchStrategy.INHERITED_ANNOTATIONS);
MergedAnnotations annotations = MergedAnnotations.from(ao);
for (Class<? extends Annotation> type : this.autowiredAnnotationTypes) {
MergedAnnotation<?> annotation = annotations.get(type);
if (annotation.isPresent()) {
@ -533,7 +532,7 @@ public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBean @@ -533,7 +532,7 @@ public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBean
* @param ann the Autowired annotation
* @return whether the annotation indicates that a dependency is required
*/
@SuppressWarnings({ "deprecation", "cast" })
@SuppressWarnings({"deprecation", "cast"})
protected boolean determineRequiredStatus(MergedAnnotation<?> ann) {
// The following (AnnotationAttributes) cast is required on JDK 9+.
return determineRequiredStatus((AnnotationAttributes)

3
spring-context/src/main/java/org/springframework/jmx/export/annotation/AnnotationJmxAttributeSource.java

@ -35,7 +35,6 @@ import org.springframework.beans.factory.BeanFactory; @@ -35,7 +35,6 @@ import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.beans.factory.config.EmbeddedValueResolver;
import org.springframework.core.annotation.AnnotationFilter;
import org.springframework.core.annotation.MergedAnnotation;
import org.springframework.core.annotation.MergedAnnotationPredicates;
import org.springframework.core.annotation.MergedAnnotations;
@ -168,7 +167,7 @@ public class AnnotationJmxAttributeSource implements JmxAttributeSource, BeanFac @@ -168,7 +167,7 @@ public class AnnotationJmxAttributeSource implements JmxAttributeSource, BeanFac
Class<? extends Annotation> containerAnnotationType) {
return MergedAnnotations.from(annotatedElement, SearchStrategy.TYPE_HIERARCHY,
RepeatableContainers.of(annotationType, containerAnnotationType), AnnotationFilter.PLAIN)
RepeatableContainers.of(annotationType, containerAnnotationType))
.stream(annotationType)
.filter(MergedAnnotationPredicates.firstRunOf(MergedAnnotation::getAggregateIndex))
.map(MergedAnnotation::withNonMergedAttributes)

12
spring-core/src/main/java/org/springframework/core/annotation/AnnotatedElementUtils.java

@ -750,29 +750,25 @@ public abstract class AnnotatedElementUtils { @@ -750,29 +750,25 @@ public abstract class AnnotatedElementUtils {
}
private static MergedAnnotations getAnnotations(AnnotatedElement element) {
return MergedAnnotations.from(element, SearchStrategy.INHERITED_ANNOTATIONS,
RepeatableContainers.none(), AnnotationFilter.PLAIN);
return MergedAnnotations.from(element, SearchStrategy.INHERITED_ANNOTATIONS, RepeatableContainers.none());
}
private static MergedAnnotations getRepeatableAnnotations(AnnotatedElement element,
@Nullable Class<? extends Annotation> containerType, Class<? extends Annotation> annotationType) {
RepeatableContainers repeatableContainers = RepeatableContainers.of(annotationType, containerType);
return MergedAnnotations.from(element, SearchStrategy.INHERITED_ANNOTATIONS,
repeatableContainers, AnnotationFilter.PLAIN);
return MergedAnnotations.from(element, SearchStrategy.INHERITED_ANNOTATIONS, repeatableContainers);
}
private static MergedAnnotations findAnnotations(AnnotatedElement element) {
return MergedAnnotations.from(element, SearchStrategy.TYPE_HIERARCHY,
RepeatableContainers.none(), AnnotationFilter.PLAIN);
return MergedAnnotations.from(element, SearchStrategy.TYPE_HIERARCHY, RepeatableContainers.none());
}
private static MergedAnnotations findRepeatableAnnotations(AnnotatedElement element,
@Nullable Class<? extends Annotation> containerType, Class<? extends Annotation> annotationType) {
RepeatableContainers repeatableContainers = RepeatableContainers.of(annotationType, containerType);
return MergedAnnotations.from(element, SearchStrategy.TYPE_HIERARCHY,
repeatableContainers, AnnotationFilter.PLAIN);
return MergedAnnotations.from(element, SearchStrategy.TYPE_HIERARCHY, repeatableContainers);
}
@Nullable

33
spring-core/src/main/java/org/springframework/core/annotation/AnnotationFilter.java

@ -40,11 +40,42 @@ public interface AnnotationFilter { @@ -40,11 +40,42 @@ public interface AnnotationFilter {
*/
AnnotationFilter JAVA = packages("java", "javax");
/**
* {@link AnnotationFilter} that always matches and can be used when no
* relevant annotation types are expected to present at all.
*/
AnnotationFilter ALL = new AnnotationFilter() {
@Override
public boolean matches(Annotation annotation) {
return true;
}
@Override
public boolean matches(Class<?> type) {
return true;
}
@Override
public boolean matches(String typeName) {
return true;
}
@Override
public String toString() {
return "All annotations filtered";
}
};
/**
* {@link AnnotationFilter} that never matches and can be used when no
* filtering is needed.
* filtering is needed (allowing for any annotation types to be present).
*/
AnnotationFilter NONE = new AnnotationFilter() {
@Override
public boolean matches(Annotation annotation) {
return false;
}
@Override
public boolean matches(Class<?> type) {
return false;
}
@Override
public boolean matches(String typeName) {
return false;

28
spring-core/src/main/java/org/springframework/core/annotation/AnnotationUtils.java

@ -112,7 +112,7 @@ public abstract class AnnotationUtils { @@ -112,7 +112,7 @@ public abstract class AnnotationUtils {
private static final AnnotationFilter JAVA_LANG_ANNOTATION_FILTER =
AnnotationFilter.packages("java.lang.annotation");
private static Map<Class<? extends Annotation>, Map<String, DefaultValueHolder>> defaultValuesCache =
private static final Map<Class<? extends Annotation>, Map<String, DefaultValueHolder>> defaultValuesCache =
new ConcurrentReferenceHashMap<>();
@ -126,6 +126,7 @@ public abstract class AnnotationUtils { @@ -126,6 +126,7 @@ public abstract class AnnotationUtils {
* if {@code true} is being returned here.
* @since 5.2
* @see #isCandidateClass(Class, Class)
* @see #isCandidateClass(Class, String)
*/
public static boolean isCandidateClass(Class<?> clazz, Collection<Class<? extends Annotation>> annotationTypes) {
for (Class<? extends Annotation> annotationType : annotationTypes) {
@ -160,6 +161,7 @@ public abstract class AnnotationUtils { @@ -160,6 +161,7 @@ public abstract class AnnotationUtils {
* {@code true} otherwise. Callers will usually perform full method/field introspection
* if {@code true} is being returned here.
* @since 5.2
* @see #isCandidateClass(Class, Class)
*/
public static boolean isCandidateClass(Class<?> clazz, String annotationName) {
if (annotationName.startsWith("java.")) {
@ -196,8 +198,7 @@ public abstract class AnnotationUtils { @@ -196,8 +198,7 @@ public abstract class AnnotationUtils {
return null;
}
// Exhaustive retrieval of merged annotations...
return MergedAnnotations.from(null, new Annotation[] {annotation},
RepeatableContainers.none(), AnnotationFilter.PLAIN)
return MergedAnnotations.from(annotation, new Annotation[] {annotation}, RepeatableContainers.none())
.get(annotationType).withNonMergedAttributes()
.synthesize(AnnotationUtils::isSingleLevelPresent).orElse(null);
}
@ -222,8 +223,7 @@ public abstract class AnnotationUtils { @@ -222,8 +223,7 @@ public abstract class AnnotationUtils {
return annotatedElement.getAnnotation(annotationType);
}
// Exhaustive retrieval of merged annotations...
return MergedAnnotations.from(annotatedElement, SearchStrategy.INHERITED_ANNOTATIONS,
RepeatableContainers.none(), AnnotationFilter.PLAIN)
return MergedAnnotations.from(annotatedElement, SearchStrategy.INHERITED_ANNOTATIONS, RepeatableContainers.none())
.get(annotationType).withNonMergedAttributes()
.synthesize(AnnotationUtils::isSingleLevelPresent).orElse(null);
}
@ -375,8 +375,7 @@ public abstract class AnnotationUtils { @@ -375,8 +375,7 @@ public abstract class AnnotationUtils {
RepeatableContainers repeatableContainers = (containerAnnotationType != null ?
RepeatableContainers.of(annotationType, containerAnnotationType) :
RepeatableContainers.standardRepeatables());
return MergedAnnotations.from(annotatedElement, SearchStrategy.SUPERCLASS,
repeatableContainers, AnnotationFilter.PLAIN)
return MergedAnnotations.from(annotatedElement, SearchStrategy.SUPERCLASS, repeatableContainers)
.stream(annotationType)
.filter(MergedAnnotationPredicates.firstRunOf(MergedAnnotation::getAggregateIndex))
.map(MergedAnnotation::withNonMergedAttributes)
@ -457,8 +456,8 @@ public abstract class AnnotationUtils { @@ -457,8 +456,8 @@ public abstract class AnnotationUtils {
RepeatableContainers repeatableContainers = containerAnnotationType != null ?
RepeatableContainers.of(annotationType, containerAnnotationType) :
RepeatableContainers.standardRepeatables();
return MergedAnnotations.from(annotatedElement, SearchStrategy.DIRECT,
repeatableContainers, AnnotationFilter.PLAIN).stream(annotationType)
return MergedAnnotations.from(annotatedElement, SearchStrategy.DIRECT, repeatableContainers)
.stream(annotationType)
.map(MergedAnnotation::withNonMergedAttributes)
.collect(MergedAnnotationCollectors.toAnnotationSet());
}
@ -492,8 +491,7 @@ public abstract class AnnotationUtils { @@ -492,8 +491,7 @@ public abstract class AnnotationUtils {
return annotatedElement.getDeclaredAnnotation(annotationType);
}
// Exhaustive retrieval of merged annotations...
return MergedAnnotations.from(annotatedElement, SearchStrategy.INHERITED_ANNOTATIONS,
RepeatableContainers.none(), AnnotationFilter.PLAIN)
return MergedAnnotations.from(annotatedElement, SearchStrategy.INHERITED_ANNOTATIONS, RepeatableContainers.none())
.get(annotationType).withNonMergedAttributes()
.synthesize(MergedAnnotation::isPresent).orElse(null);
}
@ -524,8 +522,7 @@ public abstract class AnnotationUtils { @@ -524,8 +522,7 @@ public abstract class AnnotationUtils {
return method.getDeclaredAnnotation(annotationType);
}
// Exhaustive retrieval of merged annotations...
return MergedAnnotations.from(method, SearchStrategy.TYPE_HIERARCHY,
RepeatableContainers.none(), AnnotationFilter.PLAIN)
return MergedAnnotations.from(method, SearchStrategy.TYPE_HIERARCHY, RepeatableContainers.none())
.get(annotationType).withNonMergedAttributes()
.synthesize(MergedAnnotation::isPresent).orElse(null);
}
@ -563,8 +560,7 @@ public abstract class AnnotationUtils { @@ -563,8 +560,7 @@ public abstract class AnnotationUtils {
return clazz.getDeclaredAnnotation(annotationType);
}
// Exhaustive retrieval of merged annotations...
return MergedAnnotations.from(clazz, SearchStrategy.TYPE_HIERARCHY,
RepeatableContainers.none(), AnnotationFilter.PLAIN)
return MergedAnnotations.from(clazz, SearchStrategy.TYPE_HIERARCHY, RepeatableContainers.none())
.get(annotationType).withNonMergedAttributes()
.synthesize(MergedAnnotation::isPresent).orElse(null);
}
@ -714,7 +710,7 @@ public abstract class AnnotationUtils { @@ -714,7 +710,7 @@ public abstract class AnnotationUtils {
}
// Exhaustive retrieval of merged annotations...
return MergedAnnotations.from(annotationType, SearchStrategy.INHERITED_ANNOTATIONS,
RepeatableContainers.none(), AnnotationFilter.PLAIN).isPresent(metaAnnotationType);
RepeatableContainers.none()).isPresent(metaAnnotationType);
}
/**

43
spring-core/src/main/java/org/springframework/core/annotation/MergedAnnotations.java

@ -53,7 +53,6 @@ import org.springframework.lang.Nullable; @@ -53,7 +53,6 @@ import org.springframework.lang.Nullable;
*
* &#064;AliasFor(attribute = "value")
* String[] path() default {};
*
* }
* </pre>
*
@ -303,7 +302,24 @@ public interface MergedAnnotations extends Iterable<MergedAnnotation<Annotation> @@ -303,7 +302,24 @@ public interface MergedAnnotations extends Iterable<MergedAnnotation<Annotation>
* element annotations
*/
static MergedAnnotations from(AnnotatedElement element, SearchStrategy searchStrategy) {
return from(element, searchStrategy, RepeatableContainers.standardRepeatables(), AnnotationFilter.PLAIN);
return from(element, searchStrategy, RepeatableContainers.standardRepeatables());
}
/**
* Create a new {@link MergedAnnotations} instance containing all
* annotations and meta-annotations from the specified element and,
* depending on the {@link SearchStrategy}, related inherited elements.
* @param element the source element
* @param searchStrategy the search strategy to use
* @param repeatableContainers the repeatable containers that may be used by
* the element annotations or the meta-annotations
* @return a {@link MergedAnnotations} instance containing the merged
* element annotations
*/
static MergedAnnotations from(AnnotatedElement element, SearchStrategy searchStrategy,
RepeatableContainers repeatableContainers) {
return TypeMappedAnnotations.from(element, searchStrategy, repeatableContainers, AnnotationFilter.PLAIN);
}
/**
@ -333,7 +349,7 @@ public interface MergedAnnotations extends Iterable<MergedAnnotation<Annotation> @@ -333,7 +349,7 @@ public interface MergedAnnotations extends Iterable<MergedAnnotation<Annotation>
* @see #from(Object, Annotation...)
*/
static MergedAnnotations from(Annotation... annotations) {
return from(null, annotations);
return from(annotations, annotations);
}
/**
@ -347,8 +363,23 @@ public interface MergedAnnotations extends Iterable<MergedAnnotation<Annotation> @@ -347,8 +363,23 @@ public interface MergedAnnotations extends Iterable<MergedAnnotation<Annotation>
* @see #from(Annotation...)
* @see #from(AnnotatedElement)
*/
static MergedAnnotations from(@Nullable Object source, Annotation... annotations) {
return from(source, annotations, RepeatableContainers.standardRepeatables(), AnnotationFilter.PLAIN);
static MergedAnnotations from(Object source, Annotation... annotations) {
return from(source, annotations, RepeatableContainers.standardRepeatables());
}
/**
* Create a new {@link MergedAnnotations} instance from the specified
* annotations.
* @param source the source for the annotations. This source is used only
* for information and logging. It does not need to <em>actually</em>
* contain the specified annotations, and it will not be searched.
* @param annotations the annotations to include
* @param repeatableContainers the repeatable containers that may be used by
* meta-annotations
* @return a {@link MergedAnnotations} instance containing the annotations
*/
static MergedAnnotations from(Object source, Annotation[] annotations, RepeatableContainers repeatableContainers) {
return TypeMappedAnnotations.from(source, annotations, repeatableContainers, AnnotationFilter.PLAIN);
}
/**
@ -364,7 +395,7 @@ public interface MergedAnnotations extends Iterable<MergedAnnotation<Annotation> @@ -364,7 +395,7 @@ public interface MergedAnnotations extends Iterable<MergedAnnotation<Annotation>
* annotations considered
* @return a {@link MergedAnnotations} instance containing the annotations
*/
static MergedAnnotations from(@Nullable Object source, Annotation[] annotations,
static MergedAnnotations from(Object source, Annotation[] annotations,
RepeatableContainers repeatableContainers, AnnotationFilter annotationFilter) {
return TypeMappedAnnotations.from(source, annotations, repeatableContainers, annotationFilter);

21
spring-core/src/main/java/org/springframework/core/annotation/TypeMappedAnnotations.java

@ -40,13 +40,11 @@ import org.springframework.lang.Nullable; @@ -40,13 +40,11 @@ import org.springframework.lang.Nullable;
*/
final class TypeMappedAnnotations implements MergedAnnotations {
private static final AnnotationFilter FILTER_ALL = (annotationType -> true);
/**
* Shared instance that can be used when there are no annotations.
*/
static final MergedAnnotations NONE = new TypeMappedAnnotations(
null, new Annotation[0], RepeatableContainers.none(), FILTER_ALL);
null, new Annotation[0], RepeatableContainers.none(), AnnotationFilter.ALL);
@Nullable
@ -180,7 +178,7 @@ final class TypeMappedAnnotations implements MergedAnnotations { @@ -180,7 +178,7 @@ final class TypeMappedAnnotations implements MergedAnnotations {
@Override
public <A extends Annotation> Stream<MergedAnnotation<A>> stream(Class<A> annotationType) {
if (this.annotationFilter == FILTER_ALL) {
if (this.annotationFilter == AnnotationFilter.ALL) {
return Stream.empty();
}
return StreamSupport.stream(spliterator(annotationType), false);
@ -188,7 +186,7 @@ final class TypeMappedAnnotations implements MergedAnnotations { @@ -188,7 +186,7 @@ final class TypeMappedAnnotations implements MergedAnnotations {
@Override
public <A extends Annotation> Stream<MergedAnnotation<A>> stream(String annotationType) {
if (this.annotationFilter == FILTER_ALL) {
if (this.annotationFilter == AnnotationFilter.ALL) {
return Stream.empty();
}
return StreamSupport.stream(spliterator(annotationType), false);
@ -196,7 +194,7 @@ final class TypeMappedAnnotations implements MergedAnnotations { @@ -196,7 +194,7 @@ final class TypeMappedAnnotations implements MergedAnnotations {
@Override
public Stream<MergedAnnotation<Annotation>> stream() {
if (this.annotationFilter == FILTER_ALL) {
if (this.annotationFilter == AnnotationFilter.ALL) {
return Stream.empty();
}
return StreamSupport.stream(spliterator(), false);
@ -204,7 +202,7 @@ final class TypeMappedAnnotations implements MergedAnnotations { @@ -204,7 +202,7 @@ final class TypeMappedAnnotations implements MergedAnnotations {
@Override
public Iterator<MergedAnnotation<Annotation>> iterator() {
if (this.annotationFilter == FILTER_ALL) {
if (this.annotationFilter == AnnotationFilter.ALL) {
return Collections.emptyIterator();
}
return Spliterators.iterator(spliterator());
@ -212,7 +210,7 @@ final class TypeMappedAnnotations implements MergedAnnotations { @@ -212,7 +210,7 @@ final class TypeMappedAnnotations implements MergedAnnotations {
@Override
public Spliterator<MergedAnnotation<Annotation>> spliterator() {
if (this.annotationFilter == FILTER_ALL) {
if (this.annotationFilter == AnnotationFilter.ALL) {
return Collections.<MergedAnnotation<Annotation>> emptyList().spliterator();
}
return spliterator(null);
@ -510,8 +508,7 @@ final class TypeMappedAnnotations implements MergedAnnotations { @@ -510,8 +508,7 @@ final class TypeMappedAnnotations implements MergedAnnotations {
this.annotations = annotations;
this.mappings = new AnnotationTypeMappings[annotations.size()];
for (int i = 0; i < annotations.size(); i++) {
this.mappings[i] = AnnotationTypeMappings.forAnnotationType(
annotations.get(i).annotationType());
this.mappings[i] = AnnotationTypeMappings.forAnnotationType(annotations.get(i).annotationType());
}
}
@ -531,8 +528,8 @@ final class TypeMappedAnnotations implements MergedAnnotations { @@ -531,8 +528,8 @@ final class TypeMappedAnnotations implements MergedAnnotations {
@Nullable
<A extends Annotation> MergedAnnotation<A> createMergedAnnotationIfPossible(
int annotationIndex, int mappingIndex,
IntrospectionFailureLogger logger) {
int annotationIndex, int mappingIndex, IntrospectionFailureLogger logger) {
return TypeMappedAnnotation.createIfPossible(
this.mappings[annotationIndex].get(mappingIndex), this.source,
this.annotations.get(annotationIndex), this.aggregateIndex, logger);

7
spring-core/src/main/java/org/springframework/core/type/StandardMethodMetadata.java

@ -21,7 +21,6 @@ import java.lang.reflect.Modifier; @@ -21,7 +21,6 @@ import java.lang.reflect.Modifier;
import java.util.Map;
import org.springframework.core.annotation.AnnotatedElementUtils;
import org.springframework.core.annotation.AnnotationFilter;
import org.springframework.core.annotation.MergedAnnotations;
import org.springframework.core.annotation.MergedAnnotations.SearchStrategy;
import org.springframework.core.annotation.RepeatableContainers;
@ -75,11 +74,11 @@ public class StandardMethodMetadata implements MethodMetadata { @@ -75,11 +74,11 @@ public class StandardMethodMetadata implements MethodMetadata {
Assert.notNull(introspectedMethod, "Method must not be null");
this.introspectedMethod = introspectedMethod;
this.nestedAnnotationsAsMap = nestedAnnotationsAsMap;
this.mergedAnnotations = MergedAnnotations.from(introspectedMethod,
SearchStrategy.DIRECT, RepeatableContainers.none(),
AnnotationFilter.PLAIN);
this.mergedAnnotations = MergedAnnotations.from(
introspectedMethod, SearchStrategy.DIRECT, RepeatableContainers.none());
}
@Override
public MergedAnnotations getAnnotations() {
return this.mergedAnnotations;

Loading…
Cancel
Save