Skip to content

Commit

Permalink
Deprecate "enclosing classes" search strategy for MergedAnnotations
Browse files Browse the repository at this point in the history
The TYPE_HIERARCHY_AND_ENCLOSING_CLASSES search strategy for
MergedAnnotations was originally introduced to support @nested test
classes in JUnit Jupiter (see spring-projects#23378).

However, while implementing spring-projects#19930, we determined that the
TYPE_HIERARCHY_AND_ENCLOSING_CLASSES search strategy unfortunately
could not be used since it does not allow the user to control when to
recurse up the enclosing class hierarchy. For example, this search
strategy will automatically search on enclosing classes for static
nested classes as well as for inner classes, when the user probably
only wants one such category of "enclosing class" to be searched.
Consequently, TestContextAnnotationUtils was introduced in the Spring
TestContext Framework to address the shortcomings of the
TYPE_HIERARCHY_AND_ENCLOSING_CLASSES search strategy.

Since this search strategy is unlikely to be useful to general users,
the team has decided to deprecate this search strategy in Spring
Framework 5.3.x and remove it in 6.0.

Closes spring-projectsgh-28079
  • Loading branch information
sbrannen committed Feb 19, 2022
1 parent 071c298 commit 5689395
Show file tree
Hide file tree
Showing 4 changed files with 12 additions and 2 deletions.
Original file line number Diff line number Diff line change
@@ -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.
Expand Down Expand Up @@ -92,6 +92,7 @@ private static <C, R> R process(C context, AnnotatedElement source,
}

@Nullable
@SuppressWarnings("deprecation")
private static <C, R> R processClass(C context, Class<?> source,
SearchStrategy searchStrategy, AnnotationsProcessor<C, R> processor) {

Expand Down Expand Up @@ -235,6 +236,7 @@ private static <C, R> R processClassHierarchy(C context, int[] aggregateIndex, C
}

@Nullable
@SuppressWarnings("deprecation")
private static <C, R> R processMethod(C context, Method source,
SearchStrategy searchStrategy, AnnotationsProcessor<C, R> processor) {

Expand Down Expand Up @@ -510,6 +512,7 @@ static boolean hasPlainJavaAnnotationsOnly(Class<?> type) {
return (type.getName().startsWith("java.") || type == Ordered.class);
}

@SuppressWarnings("deprecation")
private static boolean isWithoutHierarchy(AnnotatedElement source, SearchStrategy searchStrategy) {
if (source == Object.class) {
return true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -482,7 +482,9 @@ enum SearchStrategy {
* 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
}

Expand Down
Original file line number Diff line number Diff line change
@@ -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.
Expand Down Expand Up @@ -421,20 +421,23 @@ void typeHierarchyStrategyOnMethodWithGenericParameterNonOverrideScansAnnotation
}

@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(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -712,13 +712,15 @@ void streamTypeHierarchyFromClassWithInterface() throws Exception {
}

@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);
Expand Down

0 comments on commit 5689395

Please sign in to comment.