Remove deprecated "enclosing classes" search strategy for MergedAnnotations
Closes gh-28080
This commit is contained in:
parent
ad3095f197
commit
819d4256b7
|
@ -99,9 +99,8 @@ abstract class AnnotationsScanner {
|
|||
return switch (searchStrategy) {
|
||||
case DIRECT -> processElement(context, source, processor);
|
||||
case INHERITED_ANNOTATIONS -> processClassInheritedAnnotations(context, source, searchStrategy, processor);
|
||||
case SUPERCLASS -> processClassHierarchy(context, source, processor, false, false);
|
||||
case TYPE_HIERARCHY -> processClassHierarchy(context, source, processor, true, false);
|
||||
case TYPE_HIERARCHY_AND_ENCLOSING_CLASSES -> processClassHierarchy(context, source, processor, true, true);
|
||||
case SUPERCLASS -> processClassHierarchy(context, source, processor, false);
|
||||
case TYPE_HIERARCHY -> processClassHierarchy(context, source, processor, true);
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -161,15 +160,14 @@ abstract class AnnotationsScanner {
|
|||
|
||||
@Nullable
|
||||
private static <C, R> R processClassHierarchy(C context, Class<?> source,
|
||||
AnnotationsProcessor<C, R> processor, boolean includeInterfaces, boolean includeEnclosing) {
|
||||
AnnotationsProcessor<C, R> processor, boolean includeInterfaces) {
|
||||
|
||||
return processClassHierarchy(context, new int[] {0}, source, processor,
|
||||
includeInterfaces, includeEnclosing);
|
||||
return processClassHierarchy(context, new int[] {0}, source, processor, includeInterfaces);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static <C, R> R processClassHierarchy(C context, int[] aggregateIndex, Class<?> source,
|
||||
AnnotationsProcessor<C, R> processor, boolean includeInterfaces, boolean includeEnclosing) {
|
||||
AnnotationsProcessor<C, R> processor, boolean includeInterfaces) {
|
||||
|
||||
try {
|
||||
R result = processor.doWithAggregate(context, aggregateIndex[0]);
|
||||
|
@ -188,7 +186,7 @@ abstract class AnnotationsScanner {
|
|||
if (includeInterfaces) {
|
||||
for (Class<?> interfaceType : source.getInterfaces()) {
|
||||
R interfacesResult = processClassHierarchy(context, aggregateIndex,
|
||||
interfaceType, processor, true, includeEnclosing);
|
||||
interfaceType, processor, true);
|
||||
if (interfacesResult != null) {
|
||||
return interfacesResult;
|
||||
}
|
||||
|
@ -197,31 +195,11 @@ abstract class AnnotationsScanner {
|
|||
Class<?> superclass = source.getSuperclass();
|
||||
if (superclass != Object.class && superclass != null) {
|
||||
R superclassResult = processClassHierarchy(context, aggregateIndex,
|
||||
superclass, processor, includeInterfaces, includeEnclosing);
|
||||
superclass, processor, includeInterfaces);
|
||||
if (superclassResult != null) {
|
||||
return superclassResult;
|
||||
}
|
||||
}
|
||||
if (includeEnclosing) {
|
||||
// Since merely attempting to load the enclosing class may result in
|
||||
// automatic loading of sibling nested classes that in turn results
|
||||
// in an exception such as NoClassDefFoundError, we wrap the following
|
||||
// in its own dedicated try-catch block in order not to preemptively
|
||||
// halt the annotation scanning process.
|
||||
try {
|
||||
Class<?> enclosingClass = source.getEnclosingClass();
|
||||
if (enclosingClass != null) {
|
||||
R enclosingResult = processClassHierarchy(context, aggregateIndex,
|
||||
enclosingClass, processor, includeInterfaces, true);
|
||||
if (enclosingResult != null) {
|
||||
return enclosingResult;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Throwable ex) {
|
||||
AnnotationUtils.handleIntrospectionFailure(source, ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Throwable ex) {
|
||||
AnnotationUtils.handleIntrospectionFailure(source, ex);
|
||||
|
@ -238,8 +216,7 @@ abstract class AnnotationsScanner {
|
|||
case DIRECT, INHERITED_ANNOTATIONS -> processMethodInheritedAnnotations(context, source, processor);
|
||||
case SUPERCLASS -> processMethodHierarchy(context, new int[]{0}, source.getDeclaringClass(),
|
||||
processor, source, false);
|
||||
case TYPE_HIERARCHY, TYPE_HIERARCHY_AND_ENCLOSING_CLASSES -> processMethodHierarchy(context, new int[]{0},
|
||||
source.getDeclaringClass(),
|
||||
case TYPE_HIERARCHY -> processMethodHierarchy(context, new int[]{0}, source.getDeclaringClass(),
|
||||
processor, source, true);
|
||||
};
|
||||
}
|
||||
|
@ -506,12 +483,8 @@ abstract class AnnotationsScanner {
|
|||
if (source == Object.class) {
|
||||
return true;
|
||||
}
|
||||
if (source instanceof Class) {
|
||||
Class<?> sourceClass = (Class<?>) source;
|
||||
boolean noSuperTypes = (sourceClass.getSuperclass() == Object.class &&
|
||||
sourceClass.getInterfaces().length == 0);
|
||||
return (searchStrategy == SearchStrategy.TYPE_HIERARCHY_AND_ENCLOSING_CLASSES ? noSuperTypes &&
|
||||
sourceClass.getEnclosingClass() == null : noSuperTypes);
|
||||
if (source instanceof Class<?> sourceClass) {
|
||||
return (sourceClass.getSuperclass() == Object.class && sourceClass.getInterfaces().length == 0);
|
||||
}
|
||||
if (source instanceof Method sourceMethod) {
|
||||
return (Modifier.isPrivate(sourceMethod.getModifiers()) ||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2020 the original author or authors.
|
||||
* Copyright 2002-2022 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.
|
||||
|
@ -472,20 +472,8 @@ public interface MergedAnnotations extends Iterable<MergedAnnotation<Annotation>
|
|||
* superclasses and implemented interfaces. Superclass annotations do
|
||||
* not need to be meta-annotated with {@link Inherited @Inherited}.
|
||||
*/
|
||||
TYPE_HIERARCHY,
|
||||
TYPE_HIERARCHY
|
||||
|
||||
/**
|
||||
* Perform a full search of the entire type hierarchy on the source
|
||||
* <em>and</em> any enclosing classes. This strategy is similar to
|
||||
* {@link #TYPE_HIERARCHY} except that {@linkplain Class#getEnclosingClass()
|
||||
* enclosing classes} are also searched. Superclass annotations do not
|
||||
* need to be meta-annotated with {@link Inherited @Inherited}. When
|
||||
* searching a {@link Method} source, this strategy is identical to
|
||||
* {@link #TYPE_HIERARCHY}.
|
||||
* @deprecated as of Spring Framework 5.3.17; to be removed in Spring Framework 6.0
|
||||
*/
|
||||
@Deprecated
|
||||
TYPE_HIERARCHY_AND_ENCLOSING_CLASSES
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -420,32 +420,6 @@ class AnnotationsScannerTests {
|
|||
assertThat(scan(source, SearchStrategy.TYPE_HIERARCHY)).containsExactly("0:TestAnnotation1");
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("deprecation")
|
||||
void typeHierarchyWithEnclosedStrategyOnEnclosedStaticClassScansAnnotations() {
|
||||
Class<?> source = AnnotationEnclosingClassSample.EnclosedStatic.EnclosedStaticStatic.class;
|
||||
assertThat(scan(source, SearchStrategy.TYPE_HIERARCHY_AND_ENCLOSING_CLASSES))
|
||||
.containsExactly("0:EnclosedThree", "1:EnclosedTwo", "2:EnclosedOne");
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("deprecation")
|
||||
void typeHierarchyWithEnclosedStrategyOnEnclosedInnerClassScansAnnotations() {
|
||||
Class<?> source = AnnotationEnclosingClassSample.EnclosedInner.EnclosedInnerInner.class;
|
||||
assertThat(scan(source, SearchStrategy.TYPE_HIERARCHY_AND_ENCLOSING_CLASSES))
|
||||
.containsExactly("0:EnclosedThree", "1:EnclosedTwo", "2:EnclosedOne");
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("deprecation")
|
||||
void typeHierarchyWithEnclosedStrategyOnMethodHierarchyUsesTypeHierarchyScan() {
|
||||
Method source = methodFrom(WithHierarchy.class);
|
||||
assertThat(scan(source, SearchStrategy.TYPE_HIERARCHY_AND_ENCLOSING_CLASSES)).containsExactly(
|
||||
"0:TestAnnotation1", "1:TestAnnotation5", "1:TestInheritedAnnotation5",
|
||||
"2:TestAnnotation6", "3:TestAnnotation2", "3:TestInheritedAnnotation2",
|
||||
"4:TestAnnotation3", "5:TestAnnotation4");
|
||||
}
|
||||
|
||||
@Test
|
||||
void scanWhenProcessorReturnsFromDoWithAggregateExitsEarly() {
|
||||
String result = AnnotationsScanner.scan(this, WithSingleSuperclass.class,
|
||||
|
|
|
@ -710,22 +710,6 @@ class MergedAnnotationsTests {
|
|||
Transactional.class)).hasSize(1);
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("deprecation")
|
||||
void streamTypeHierarchyAndEnclosingClassesFromNonAnnotatedInnerClassWithAnnotatedEnclosingClass() {
|
||||
Stream<Class<?>> classes = MergedAnnotations.from(AnnotatedClass.NonAnnotatedInnerClass.class,
|
||||
SearchStrategy.TYPE_HIERARCHY_AND_ENCLOSING_CLASSES).stream().map(MergedAnnotation::getType);
|
||||
assertThat(classes).containsExactly(Component.class, Indexed.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("deprecation")
|
||||
void streamTypeHierarchyAndEnclosingClassesFromNonAnnotatedStaticNestedClassWithAnnotatedEnclosingClass() {
|
||||
Stream<Class<?>> classes = MergedAnnotations.from(AnnotatedClass.NonAnnotatedStaticNestedClass.class,
|
||||
SearchStrategy.TYPE_HIERARCHY_AND_ENCLOSING_CLASSES).stream().map(MergedAnnotation::getType);
|
||||
assertThat(classes).containsExactly(Component.class, Indexed.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
void getFromMethodWithMethodAnnotationOnLeaf() throws Exception {
|
||||
Method method = Leaf.class.getMethod("annotatedOnLeaf");
|
||||
|
|
Loading…
Reference in New Issue