Skip to content

Commit

Permalink
Find annotations on anonymous classes in AnnotationsUtils.findAnnotat…
Browse files Browse the repository at this point in the history
  • Loading branch information
janeisklar authored and sbrannen committed Oct 4, 2023
1 parent 147abc9 commit 4d86fff
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,15 @@
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.Proxy;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Stream;

import org.springframework.core.BridgeMethodResolver;
import org.springframework.core.annotation.AnnotationTypeMapping.MirrorSets.MirrorSet;
Expand Down Expand Up @@ -561,6 +564,18 @@ public static <A extends Annotation> A findAnnotation(Class<?> clazz, @Nullable
return null;
}

// check if we are dealing with an annotation on an anonymous class (no need for class hierarchy traversal)
final A annotationOnAnonymous = Stream
.concat(Stream.of(clazz.getAnnotatedSuperclass()), Arrays.stream(clazz.getAnnotatedInterfaces()))
.filter(Objects::nonNull)
.map(a -> findAnnotation(a, annotationType))
.filter(Objects::nonNull)
.findFirst()
.orElse(null);
if (annotationOnAnonymous != null) {
return annotationOnAnonymous;
}

// Shortcut: directly present on the element, with no merging needed?
if (AnnotationFilter.PLAIN.matches(annotationType) ||
AnnotationsScanner.hasPlainJavaAnnotationsOnly(clazz)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,10 @@

package org.springframework.core.annotation;

import java.io.Serializable;
import java.lang.annotation.Annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Repeatable;
import java.lang.annotation.Retention;
Expand Down Expand Up @@ -986,6 +988,21 @@ void findDeprecatedAnnotation() throws Exception {
assertThat(findAnnotation(SubclassOfDeprecatedClass.class, Deprecated.class)).isNotNull();
}

@Test
void findAnnotationOnAnonymousClassWithSuperclass() {
assertThat(findAnnotation((new @TypeUseAnnotation Object() {}).getClass(), TypeUseAnnotation.class)).isNotNull();
assertThat(findAnnotation((new @TypeUseAnnotation MetaMetaAnnotatedClass() {}).getClass(), TypeUseAnnotation.class)).isNotNull();
assertThat(findAnnotation((new Object() {}).getClass(), TypeUseAnnotation.class)).isNull();
assertThat(findAnnotation((new MetaMetaAnnotatedClass() {}).getClass(), TypeUseAnnotation.class)).isNull();
}

@Test
void findAnnotationOnAnonymousClassWithInterface() {
assertThat(findAnnotation((new @TypeUseAnnotation Serializable() {}).getClass(), TypeUseAnnotation.class)).isNotNull();
assertThat(findAnnotation((new @TypeUseAnnotation InterfaceWithMetaAnnotation() {}).getClass(), TypeUseAnnotation.class)).isNotNull();
assertThat(findAnnotation((new Serializable() {}).getClass(), TypeUseAnnotation.class)).isNull();
assertThat(findAnnotation((new InterfaceWithMetaAnnotation() {}).getClass(), TypeUseAnnotation.class)).isNull();
}

@SafeVarargs
static <T> T[] asArray(T... arr) {
Expand Down Expand Up @@ -1835,4 +1852,8 @@ static class DeprecatedClass {
static class SubclassOfDeprecatedClass extends DeprecatedClass {
}

@Target(ElementType.TYPE_USE)
@Retention(RetentionPolicy.RUNTIME)
@interface TypeUseAnnotation {
}
}

0 comments on commit 4d86fff

Please sign in to comment.