Browse Source

Add MergedAnnotations support to meta-data classes

Add `AnnotatedTypeMetaData.getAnnotations()` that can be used to access
annotation details using the `MergedAnnotations` interface.

Where possible, the existing annotation methods have been migrated to
call `getAnnotation()`, rather than needing their own implementation.

The existing ASM based meta-data implementations have not been updated
since they will be deprecated and replaced in a subsequent commit.

See gh-22884
pull/25019/head
Phillip Webb 6 years ago committed by Juergen Hoeller
parent
commit
8c2ccfe6a3
  1. 42
      spring-core/src/main/java/org/springframework/core/type/AnnotatedTypeMetadata.java
  2. 37
      spring-core/src/main/java/org/springframework/core/type/AnnotationMetadata.java
  3. 98
      spring-core/src/main/java/org/springframework/core/type/StandardAnnotationMetadata.java
  4. 28
      spring-core/src/main/java/org/springframework/core/type/StandardMethodMetadata.java
  5. 11
      spring-core/src/main/java/org/springframework/core/type/classreading/AnnotationMetadataReadingVisitor.java
  6. 6
      spring-core/src/main/java/org/springframework/core/type/classreading/MethodMetadataReadingVisitor.java
  7. 11
      spring-core/src/test/java/org/springframework/core/type/AbstractAnnotationMetadataTests.java
  8. 11
      spring-core/src/test/java/org/springframework/core/type/AbstractMethodMetadataTests.java
  9. 9
      spring-core/src/test/java/org/springframework/core/type/classreading/AnnotationMetadataReadingVisitorTests.java
  10. 11
      spring-core/src/test/java/org/springframework/core/type/classreading/MethodMetadataReadingVisitorTests.java

42
spring-core/src/main/java/org/springframework/core/type/AnnotatedTypeMetadata.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2002-2015 the original author or authors.
* Copyright 2002-2019 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.
@ -16,8 +16,15 @@ @@ -16,8 +16,15 @@
package org.springframework.core.type;
import java.lang.annotation.Annotation;
import java.util.Map;
import org.springframework.core.annotation.MergedAnnotation;
import org.springframework.core.annotation.MergedAnnotation.Adapt;
import org.springframework.core.annotation.MergedAnnotationCollectors;
import org.springframework.core.annotation.MergedAnnotationPredicates;
import org.springframework.core.annotation.MergedAnnotationSelectors;
import org.springframework.core.annotation.MergedAnnotations;
import org.springframework.lang.Nullable;
import org.springframework.util.MultiValueMap;
@ -38,6 +45,13 @@ import org.springframework.util.MultiValueMap; @@ -38,6 +45,13 @@ import org.springframework.util.MultiValueMap;
*/
public interface AnnotatedTypeMetadata {
/**
* Return annotation details based on the direct annotations of the
* underlying element.
* @return merged annotations based on the direct annotations
*/
MergedAnnotations getAnnotations();
/**
* Determine whether the underlying element has an annotation or meta-annotation
* of the given type defined.
@ -47,7 +61,9 @@ public interface AnnotatedTypeMetadata { @@ -47,7 +61,9 @@ public interface AnnotatedTypeMetadata {
* type to look for
* @return whether a matching annotation is defined
*/
boolean isAnnotated(String annotationName);
default boolean isAnnotated(String annotationName) {
return getAnnotations().isPresent(annotationName);
}
/**
* Retrieve the attributes of the annotation of the given type, if any (i.e. if
@ -78,7 +94,16 @@ public interface AnnotatedTypeMetadata { @@ -78,7 +94,16 @@ public interface AnnotatedTypeMetadata {
* {@code null} if no matching annotation is defined.
*/
@Nullable
Map<String, Object> getAnnotationAttributes(String annotationName, boolean classValuesAsString);
default Map<String, Object> getAnnotationAttributes(String annotationName,
boolean classValuesAsString) {
MergedAnnotation<Annotation> annotation = getAnnotations().get(annotationName,
null, MergedAnnotationSelectors.firstDirectlyDeclared());
if (!annotation.isPresent()) {
return null;
}
return annotation.asAnnotationAttributes(Adapt.values(classValuesAsString, true));
}
/**
* Retrieve all attributes of all annotations of the given type, if any (i.e. if
@ -109,6 +134,15 @@ public interface AnnotatedTypeMetadata { @@ -109,6 +134,15 @@ public interface AnnotatedTypeMetadata {
* @see #getAllAnnotationAttributes(String)
*/
@Nullable
MultiValueMap<String, Object> getAllAnnotationAttributes(String annotationName, boolean classValuesAsString);
default MultiValueMap<String, Object> getAllAnnotationAttributes(
String annotationName, boolean classValuesAsString) {
Adapt[] adaptations = Adapt.values(classValuesAsString, true);
return getAnnotations().stream(annotationName)
.filter(MergedAnnotationPredicates.unique(MergedAnnotation::getTypeHierarchy))
.map(MergedAnnotation::withNonMergedAttributes)
.collect(MergedAnnotationCollectors.toMultiValueMap(map ->
map.isEmpty() ? null : map, adaptations));
}
}

37
spring-core/src/main/java/org/springframework/core/type/AnnotationMetadata.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2002-2017 the original author or authors.
* Copyright 2002-2019 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.
@ -16,7 +16,14 @@ @@ -16,7 +16,14 @@
package org.springframework.core.type;
import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.Set;
import java.util.stream.Collectors;
import org.springframework.core.annotation.MergedAnnotation;
import org.springframework.core.annotation.MergedAnnotations;
import org.springframework.core.annotation.MergedAnnotations.SearchStrategy;
/**
* Interface that defines abstract access to the annotations of a specific
@ -38,7 +45,12 @@ public interface AnnotationMetadata extends ClassMetadata, AnnotatedTypeMetadata @@ -38,7 +45,12 @@ public interface AnnotationMetadata extends ClassMetadata, AnnotatedTypeMetadata
* are <em>present</em> on the underlying class.
* @return the annotation type names
*/
Set<String> getAnnotationTypes();
default Set<String> getAnnotationTypes() {
return getAnnotations().stream()
.filter(MergedAnnotation::isDirectlyPresent)
.map(annotation -> annotation.getType().getName())
.collect(Collectors.toCollection(LinkedHashSet::new));
}
/**
* Get the fully qualified class names of all meta-annotation types that
@ -47,7 +59,15 @@ public interface AnnotationMetadata extends ClassMetadata, AnnotatedTypeMetadata @@ -47,7 +59,15 @@ public interface AnnotationMetadata extends ClassMetadata, AnnotatedTypeMetadata
* type to look for
* @return the meta-annotation type names, or an empty set if none found
*/
Set<String> getMetaAnnotationTypes(String annotationName);
default Set<String> getMetaAnnotationTypes(String annotationName) {
MergedAnnotation<?> annotation = getAnnotations().get(annotationName, MergedAnnotation::isDirectlyPresent);
if (!annotation.isPresent()) {
return Collections.emptySet();
}
return MergedAnnotations.from(annotation.getType(), SearchStrategy.INHERITED_ANNOTATIONS).stream()
.map(mergedAnnotation -> mergedAnnotation.getType().getName())
.collect(Collectors.toCollection(LinkedHashSet::new));
}
/**
* Determine whether an annotation of the given type is <em>present</em> on
@ -57,7 +77,7 @@ public interface AnnotationMetadata extends ClassMetadata, AnnotatedTypeMetadata @@ -57,7 +77,7 @@ public interface AnnotationMetadata extends ClassMetadata, AnnotatedTypeMetadata
* @return {@code true} if a matching annotation is present
*/
default boolean hasAnnotation(String annotationName) {
return getAnnotationTypes().contains(annotationName);
return getAnnotations().isDirectlyPresent(annotationName);
}
/**
@ -67,7 +87,10 @@ public interface AnnotationMetadata extends ClassMetadata, AnnotatedTypeMetadata @@ -67,7 +87,10 @@ public interface AnnotationMetadata extends ClassMetadata, AnnotatedTypeMetadata
* meta-annotation type to look for
* @return {@code true} if a matching meta-annotation is present
*/
boolean hasMetaAnnotation(String metaAnnotationName);
default boolean hasMetaAnnotation(String metaAnnotationName) {
return getAnnotations().get(metaAnnotationName,
MergedAnnotation::isMetaPresent).isPresent();
}
/**
* Determine whether the underlying class has any methods that are
@ -75,7 +98,9 @@ public interface AnnotationMetadata extends ClassMetadata, AnnotatedTypeMetadata @@ -75,7 +98,9 @@ public interface AnnotationMetadata extends ClassMetadata, AnnotatedTypeMetadata
* @param annotationName the fully qualified class name of the annotation
* type to look for
*/
boolean hasAnnotatedMethods(String annotationName);
default boolean hasAnnotatedMethods(String annotationName) {
return !getAnnotatedMethods(annotationName).isEmpty();
}
/**
* Retrieve the method metadata for all methods that are annotated

98
spring-core/src/main/java/org/springframework/core/type/StandardAnnotationMetadata.java

@ -24,7 +24,11 @@ import java.util.Map; @@ -24,7 +24,11 @@ import java.util.Map;
import java.util.Set;
import org.springframework.core.annotation.AnnotatedElementUtils;
import org.springframework.core.annotation.AnnotationFilter;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.core.annotation.MergedAnnotations;
import org.springframework.core.annotation.MergedAnnotations.SearchStrategy;
import org.springframework.core.annotation.RepeatableContainers;
import org.springframework.lang.Nullable;
import org.springframework.util.MultiValueMap;
import org.springframework.util.ReflectionUtils;
@ -42,10 +46,11 @@ import org.springframework.util.ReflectionUtils; @@ -42,10 +46,11 @@ import org.springframework.util.ReflectionUtils;
*/
public class StandardAnnotationMetadata extends StandardClassMetadata implements AnnotationMetadata {
private final Annotation[] annotations;
private final MergedAnnotations mergedAnnotations;
private final boolean nestedAnnotationsAsMap;
private Set<String> annotationTypes;
/**
* Create a new {@code StandardAnnotationMetadata} wrapper for the given Class.
@ -69,72 +74,49 @@ public class StandardAnnotationMetadata extends StandardClassMetadata implements @@ -69,72 +74,49 @@ public class StandardAnnotationMetadata extends StandardClassMetadata implements
*/
public StandardAnnotationMetadata(Class<?> introspectedClass, boolean nestedAnnotationsAsMap) {
super(introspectedClass);
this.annotations = introspectedClass.getDeclaredAnnotations();
this.mergedAnnotations = MergedAnnotations.from(introspectedClass,
SearchStrategy.DIRECT, RepeatableContainers.none(),
AnnotationFilter.NONE);
this.nestedAnnotationsAsMap = nestedAnnotationsAsMap;
}
@Override
public Set<String> getAnnotationTypes() {
Set<String> types = new LinkedHashSet<>();
for (Annotation ann : this.annotations) {
if (!AnnotationUtils.isInJavaLangAnnotationPackage(ann.annotationType().getName())) {
types.add(ann.annotationType().getName());
}
}
return types;
}
@Override
public Set<String> getMetaAnnotationTypes(String annotationName) {
if (AnnotationUtils.isInJavaLangAnnotationPackage(annotationName)) {
return Collections.emptySet();
}
return (this.annotations.length > 0 ?
AnnotatedElementUtils.getMetaAnnotationTypes(getIntrospectedClass(), annotationName) :
Collections.emptySet());
public MergedAnnotations getAnnotations() {
return this.mergedAnnotations;
}
@Override
public boolean hasAnnotation(String annotationName) {
if (AnnotationUtils.isInJavaLangAnnotationPackage(annotationName)) {
return false;
}
for (Annotation ann : this.annotations) {
if (ann.annotationType().getName().equals(annotationName)) {
return true;
}
}
return false;
}
@Override
public boolean hasMetaAnnotation(String annotationName) {
if (AnnotationUtils.isInJavaLangAnnotationPackage(annotationName)) {
return false;
public Set<String> getAnnotationTypes() {
Set<String> annotationTypes = this.annotationTypes;
if (annotationTypes == null) {
annotationTypes = Collections.unmodifiableSet(
AnnotationMetadata.super.getAnnotationTypes());
this.annotationTypes = annotationTypes;
}
return (this.annotations.length > 0 &&
AnnotatedElementUtils.hasMetaAnnotationTypes(getIntrospectedClass(), annotationName));
}
@Override
public boolean isAnnotated(String annotationName) {
return (this.annotations.length > 0 &&
AnnotatedElementUtils.isAnnotated(getIntrospectedClass(), annotationName));
return annotationTypes;
}
@Override
@Nullable
public Map<String, Object> getAnnotationAttributes(String annotationName, boolean classValuesAsString) {
return (this.annotations.length > 0 ? AnnotatedElementUtils.getMergedAnnotationAttributes(
getIntrospectedClass(), annotationName, classValuesAsString, this.nestedAnnotationsAsMap) : null);
if (this.nestedAnnotationsAsMap) {
return AnnotationMetadata.super.getAnnotationAttributes(annotationName,
classValuesAsString);
}
return AnnotatedElementUtils.getMergedAnnotationAttributes(
getIntrospectedClass(), annotationName, classValuesAsString, this.nestedAnnotationsAsMap);
}
@Override
@Nullable
public MultiValueMap<String, Object> getAllAnnotationAttributes(String annotationName, boolean classValuesAsString) {
return (this.annotations.length > 0 ? AnnotatedElementUtils.getAllAnnotationAttributes(
getIntrospectedClass(), annotationName, classValuesAsString, this.nestedAnnotationsAsMap) : null);
if (this.nestedAnnotationsAsMap) {
return AnnotationMetadata.super.getAllAnnotationAttributes(annotationName,
classValuesAsString);
}
return AnnotatedElementUtils.getAllAnnotationAttributes(
getIntrospectedClass(), annotationName, classValuesAsString, this.nestedAnnotationsAsMap);
}
@Override
@ -143,8 +125,7 @@ public class StandardAnnotationMetadata extends StandardClassMetadata implements @@ -143,8 +125,7 @@ public class StandardAnnotationMetadata extends StandardClassMetadata implements
try {
Method[] methods = ReflectionUtils.getDeclaredMethods(getIntrospectedClass());
for (Method method : methods) {
if (!method.isBridge() && method.getAnnotations().length > 0 &&
AnnotatedElementUtils.isAnnotated(method, annotationName)) {
if (isAnnotatedMethod(method, annotationName)) {
return true;
}
}
@ -158,13 +139,15 @@ public class StandardAnnotationMetadata extends StandardClassMetadata implements @@ -158,13 +139,15 @@ public class StandardAnnotationMetadata extends StandardClassMetadata implements
@Override
public Set<MethodMetadata> getAnnotatedMethods(String annotationName) {
Set<MethodMetadata> annotatedMethods = new LinkedHashSet<>(4);
Set<MethodMetadata> annotatedMethods = null;
if (AnnotationUtils.isCandidateClass(getIntrospectedClass(), annotationName)) {
try {
Method[] methods = getIntrospectedClass().getDeclaredMethods();
Method[] methods = ReflectionUtils.getDeclaredMethods(getIntrospectedClass());
for (Method method : methods) {
if (!method.isBridge() && method.getAnnotations().length > 0 &&
AnnotatedElementUtils.isAnnotated(method, annotationName)) {
if (isAnnotatedMethod(method, annotationName)) {
if (annotatedMethods == null) {
annotatedMethods = new LinkedHashSet<>(4);
}
annotatedMethods.add(new StandardMethodMetadata(method, this.nestedAnnotationsAsMap));
}
}
@ -173,7 +156,12 @@ public class StandardAnnotationMetadata extends StandardClassMetadata implements @@ -173,7 +156,12 @@ public class StandardAnnotationMetadata extends StandardClassMetadata implements
throw new IllegalStateException("Failed to introspect annotated methods on " + getIntrospectedClass(), ex);
}
}
return annotatedMethods;
return annotatedMethods != null ? annotatedMethods : Collections.emptySet();
}
private boolean isAnnotatedMethod(Method method, String annotationName) {
return !method.isBridge() && method.getAnnotations().length > 0 &&
AnnotatedElementUtils.isAnnotated(method, annotationName);
}
}

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

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2002-2015 the original author or authors.
* Copyright 2002-2019 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.
@ -21,6 +21,10 @@ import java.lang.reflect.Modifier; @@ -21,6 +21,10 @@ 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;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.MultiValueMap;
@ -41,6 +45,8 @@ public class StandardMethodMetadata implements MethodMetadata { @@ -41,6 +45,8 @@ public class StandardMethodMetadata implements MethodMetadata {
private final boolean nestedAnnotationsAsMap;
private final MergedAnnotations mergedAnnotations;
/**
* Create a new StandardMethodMetadata wrapper for the given Method.
@ -65,8 +71,15 @@ public class StandardMethodMetadata implements MethodMetadata { @@ -65,8 +71,15 @@ 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);
}
@Override
public MergedAnnotations getAnnotations() {
return this.mergedAnnotations;
}
/**
* Return the underlying Method.
@ -107,17 +120,19 @@ public class StandardMethodMetadata implements MethodMetadata { @@ -107,17 +120,19 @@ public class StandardMethodMetadata implements MethodMetadata {
@Override
public boolean isOverridable() {
return (!isStatic() && !isFinal() && !Modifier.isPrivate(this.introspectedMethod.getModifiers()));
return !isStatic() && !isFinal() && !isPrivate();
}
@Override
public boolean isAnnotated(String annotationName) {
return AnnotatedElementUtils.isAnnotated(this.introspectedMethod, annotationName);
private boolean isPrivate() {
return Modifier.isPrivate(this.introspectedMethod.getModifiers());
}
@Override
@Nullable
public Map<String, Object> getAnnotationAttributes(String annotationName, boolean classValuesAsString) {
if (this.nestedAnnotationsAsMap) {
return MethodMetadata.super.getAnnotationAttributes(annotationName, classValuesAsString);
}
return AnnotatedElementUtils.getMergedAnnotationAttributes(this.introspectedMethod,
annotationName, classValuesAsString, this.nestedAnnotationsAsMap);
}
@ -125,6 +140,9 @@ public class StandardMethodMetadata implements MethodMetadata { @@ -125,6 +140,9 @@ public class StandardMethodMetadata implements MethodMetadata {
@Override
@Nullable
public MultiValueMap<String, Object> getAllAnnotationAttributes(String annotationName, boolean classValuesAsString) {
if (this.nestedAnnotationsAsMap) {
return MethodMetadata.super.getAllAnnotationAttributes(annotationName, classValuesAsString);
}
return AnnotatedElementUtils.getAllAnnotationAttributes(this.introspectedMethod,
annotationName, classValuesAsString, this.nestedAnnotationsAsMap);
}

11
spring-core/src/main/java/org/springframework/core/type/classreading/AnnotationMetadataReadingVisitor.java

@ -30,6 +30,7 @@ import org.springframework.asm.Opcodes; @@ -30,6 +30,7 @@ import org.springframework.asm.Opcodes;
import org.springframework.asm.Type;
import org.springframework.core.annotation.AnnotationAttributes;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.core.annotation.MergedAnnotations;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.core.type.MethodMetadata;
import org.springframework.lang.Nullable;
@ -72,6 +73,11 @@ public class AnnotationMetadataReadingVisitor extends ClassMetadataReadingVisito @@ -72,6 +73,11 @@ public class AnnotationMetadataReadingVisitor extends ClassMetadataReadingVisito
}
@Override
public MergedAnnotations getAnnotations() {
throw new UnsupportedOperationException();
}
@Override
public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
// Skip bridge methods - we're only interested in original annotation-defining user methods.
@ -129,6 +135,11 @@ public class AnnotationMetadataReadingVisitor extends ClassMetadataReadingVisito @@ -129,6 +135,11 @@ public class AnnotationMetadataReadingVisitor extends ClassMetadataReadingVisito
this.attributesMap.containsKey(annotationName));
}
@Override
public boolean hasAnnotation(String annotationName) {
return getAnnotationTypes().contains(annotationName);
}
@Override
@Nullable
public AnnotationAttributes getAnnotationAttributes(String annotationName, boolean classValuesAsString) {

6
spring-core/src/main/java/org/springframework/core/type/classreading/MethodMetadataReadingVisitor.java

@ -27,6 +27,7 @@ import org.springframework.asm.Opcodes; @@ -27,6 +27,7 @@ import org.springframework.asm.Opcodes;
import org.springframework.asm.SpringAsmInfo;
import org.springframework.asm.Type;
import org.springframework.core.annotation.AnnotationAttributes;
import org.springframework.core.annotation.MergedAnnotations;
import org.springframework.core.type.MethodMetadata;
import org.springframework.lang.Nullable;
import org.springframework.util.LinkedMultiValueMap;
@ -77,6 +78,11 @@ public class MethodMetadataReadingVisitor extends MethodVisitor implements Metho @@ -77,6 +78,11 @@ public class MethodMetadataReadingVisitor extends MethodVisitor implements Metho
}
@Override
public MergedAnnotations getAnnotations() {
throw new UnsupportedOperationException();
}
@Override
public AnnotationVisitor visitAnnotation(final String desc, boolean visible) {
if (!visible) {

11
spring-core/src/test/java/org/springframework/core/type/AbstractAnnotationMetadataTests.java

@ -21,6 +21,7 @@ import java.lang.annotation.RetentionPolicy; @@ -21,6 +21,7 @@ import java.lang.annotation.RetentionPolicy;
import org.junit.Test;
import org.springframework.core.annotation.MergedAnnotation;
import org.springframework.core.type.AbstractAnnotationMetadataTests.TestMemberClass.TestMemberClassInnerClass;
import org.springframework.core.type.AbstractAnnotationMetadataTests.TestMemberClass.TestMemberClassInnerInterface;
import org.springframework.util.MultiValueMap;
@ -137,6 +138,16 @@ public abstract class AbstractAnnotationMetadataTests { @@ -137,6 +138,16 @@ public abstract class AbstractAnnotationMetadataTests {
assertThat(get(TestClass.class).getMemberClassNames()).isEmpty();
}
@Test
public void getAnnotationsReturnsDirectAnnotations() {
AnnotationMetadata metadata = get(WithDirectAnnotations.class);
assertThat(metadata.getAnnotations().stream().filter(
MergedAnnotation::isDirectlyPresent).map(
a -> a.getType().getName())).containsExactlyInAnyOrder(
DirectAnnotation1.class.getName(),
DirectAnnotation2.class.getName());
}
@Test
public void isAnnotatedWhenMatchesDirectAnnotationReturnsTrue() {
assertThat(get(WithDirectAnnotations.class).isAnnotated(

11
spring-core/src/test/java/org/springframework/core/type/AbstractMethodMetadataTests.java

@ -21,6 +21,7 @@ import java.lang.annotation.RetentionPolicy; @@ -21,6 +21,7 @@ import java.lang.annotation.RetentionPolicy;
import org.junit.Test;
import org.springframework.core.annotation.MergedAnnotation;
import org.springframework.util.MultiValueMap;
import static org.assertj.core.api.Assertions.*;
@ -91,6 +92,16 @@ public abstract class AbstractMethodMetadataTests { @@ -91,6 +92,16 @@ public abstract class AbstractMethodMetadataTests {
assertThat(getTagged(WithPrivateMethod.class).isOverridable()).isFalse();
}
@Test
public void getAnnotationsReturnsDirectAnnotations() {
MethodMetadata metadata = getTagged(WithDirectAnnotation.class);
assertThat(metadata.getAnnotations().stream().filter(
MergedAnnotation::isDirectlyPresent).map(
a -> a.getType().getName())).containsExactlyInAnyOrder(
Tag.class.getName(),
DirectAnnotation.class.getName());
}
@Test
public void isAnnotatedWhenMatchesDirectAnnotationReturnsTrue() {
assertThat(getTagged(WithDirectAnnotation.class).isAnnotated(

9
spring-core/src/test/java/org/springframework/core/type/classreading/AnnotationMetadataReadingVisitorTests.java

@ -25,8 +25,11 @@ import org.springframework.core.io.Resource; @@ -25,8 +25,11 @@ import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
import org.springframework.core.type.AbstractAnnotationMetadataTests;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.core.type.classreading.AnnotationMetadataReadingVisitor;
import org.springframework.util.ClassUtils;
import static org.assertj.core.api.Assertions.*;
/**
* Tests for {@link AnnotationMetadataReadingVisitor}.
*
@ -58,4 +61,10 @@ public class AnnotationMetadataReadingVisitorTests @@ -58,4 +61,10 @@ public class AnnotationMetadataReadingVisitorTests
}
}
@Override
public void getAnnotationsReturnsDirectAnnotations() {
assertThatExceptionOfType(UnsupportedOperationException.class).isThrownBy(
super::getAnnotationsReturnsDirectAnnotations);
}
}

11
spring-core/src/test/java/org/springframework/core/type/classreading/MethodMetadataReadingVisitorTests.java

@ -25,13 +25,18 @@ import org.springframework.core.io.Resource; @@ -25,13 +25,18 @@ import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
import org.springframework.core.type.AbstractMethodMetadataTests;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.core.type.classreading.AnnotationMetadataReadingVisitor;
import org.springframework.core.type.classreading.MethodMetadataReadingVisitor;
import org.springframework.util.ClassUtils;
import static org.assertj.core.api.Assertions.*;
/**
* Tests for {@link MethodMetadataReadingVisitor}.
*
* @author Phillip Webb
*/
@SuppressWarnings("deprecation")
public class MethodMetadataReadingVisitorTests extends AbstractMethodMetadataTests {
@Override
@ -57,4 +62,10 @@ public class MethodMetadataReadingVisitorTests extends AbstractMethodMetadataTes @@ -57,4 +62,10 @@ public class MethodMetadataReadingVisitorTests extends AbstractMethodMetadataTes
}
}
@Override
public void getAnnotationsReturnsDirectAnnotations() {
assertThatExceptionOfType(UnsupportedOperationException.class).isThrownBy(
super::getAnnotationsReturnsDirectAnnotations);
}
}

Loading…
Cancel
Save