Skip to content

Commit b7a9b6b

Browse files
committed
Merge pull request #13904 from ayudovin:make-springbootconfigurationfinder-public-and-usable-with-annotation
* pr/13904: Polish contribution Make SpringBootConfigurationFinder public and usable with other annotations
2 parents e60af72 + f780179 commit b7a9b6b

File tree

6 files changed

+40
-17
lines changed

6 files changed

+40
-17
lines changed
Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,42 +16,63 @@
1616

1717
package org.springframework.boot.test.context;
1818

19+
import java.lang.annotation.Annotation;
1920
import java.util.Collections;
2021
import java.util.LinkedHashMap;
2122
import java.util.Map;
2223
import java.util.Set;
2324

2425
import org.springframework.beans.factory.config.BeanDefinition;
25-
import org.springframework.boot.SpringBootConfiguration;
2626
import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider;
2727
import org.springframework.core.type.filter.AnnotationTypeFilter;
2828
import org.springframework.util.Assert;
2929
import org.springframework.util.ClassUtils;
3030

3131
/**
32-
* Internal utility class to scan for a {@link SpringBootConfiguration} class.
32+
* Utility class to find a class annotated with a particular annotation in a hierarchy.
3333
*
3434
* @author Phillip Webb
35+
* @author Artsiom Yudovin
36+
* @author Stephane Nicoll
37+
* @since 2.1.0
3538
*/
36-
final class SpringBootConfigurationFinder {
39+
public final class AnnotatedClassFinder {
3740

3841
private static final Map<String, Class<?>> cache = Collections
3942
.synchronizedMap(new Cache(40));
4043

4144
private final ClassPathScanningCandidateComponentProvider scanner;
4245

43-
SpringBootConfigurationFinder() {
46+
/**
47+
* Create a new instance with the {@code annotationType} to find.
48+
* @param annotationType the annotation to find
49+
*/
50+
public AnnotatedClassFinder(Class<? extends Annotation> annotationType) {
51+
Assert.notNull(annotationType, "AnnotationType must not be null");
4452
this.scanner = new ClassPathScanningCandidateComponentProvider(false);
45-
this.scanner.addIncludeFilter(
46-
new AnnotationTypeFilter(SpringBootConfiguration.class));
53+
this.scanner.addIncludeFilter(new AnnotationTypeFilter(annotationType));
4754
this.scanner.setResourcePattern("*.class");
4855
}
4956

57+
/**
58+
* Find the first {@link Class} that is annotated with the target annotation, starting
59+
* from the package defined by the given {@code source} up to the root.
60+
* @param source the source class to use to initiate the search
61+
* @return the first {@link Class} annotated with the target annotation within the
62+
* hierarchy defined by the given {@code source} or {@code null} if none is found.
63+
*/
5064
public Class<?> findFromClass(Class<?> source) {
5165
Assert.notNull(source, "Source must not be null");
5266
return findFromPackage(ClassUtils.getPackageName(source));
5367
}
5468

69+
/**
70+
* Find the first {@link Class} that is annotated with the target annotation, starting
71+
* from the package defined by the given {@code source} up to the root.
72+
* @param source the source package to use to initiate the search
73+
* @return the first {@link Class} annotated with the target annotation within the
74+
* hierarchy defined by the given {@code source} or {@code null} if none is found.
75+
*/
5576
public Class<?> findFromPackage(String source) {
5677
Assert.notNull(source, "Source must not be null");
5778
Class<?> configuration = cache.get(source);

spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/context/SpringBootTestContextBootstrapper.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -238,7 +238,7 @@ protected Class<?>[] getOrFindConfigurationClasses(
238238
if (containsNonTestComponent(classes) || mergedConfig.hasLocations()) {
239239
return classes;
240240
}
241-
Class<?> found = new SpringBootConfigurationFinder()
241+
Class<?> found = new AnnotatedClassFinder(SpringBootConfiguration.class)
242242
.findFromClass(mergedConfig.getTestClass());
243243
Assert.state(found != null,
244244
"Unable to find a @SpringBootConfiguration, you need to use "
Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,22 +20,24 @@
2020
import org.junit.Test;
2121
import org.junit.rules.ExpectedException;
2222

23+
import org.springframework.boot.SpringBootConfiguration;
2324
import org.springframework.boot.test.context.example.ExampleConfig;
2425
import org.springframework.boot.test.context.example.scan.Example;
2526

2627
import static org.assertj.core.api.Assertions.assertThat;
2728

2829
/**
29-
* Tests for {@link SpringBootConfigurationFinder}.
30+
* Tests for {@link AnnotatedClassFinder}.
3031
*
3132
* @author Phillip Webb
3233
*/
33-
public class SpringBootConfigurationFinderTests {
34+
public class AnnotatedClassFinderTests {
3435

3536
@Rule
3637
public ExpectedException thrown = ExpectedException.none();
3738

38-
private SpringBootConfigurationFinder finder = new SpringBootConfigurationFinder();
39+
private AnnotatedClassFinder finder = new AnnotatedClassFinder(
40+
SpringBootConfiguration.class);
3941

4042
@Test
4143
public void findFromClassWhenSourceIsNullShouldThrowException() {

spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/context/example/ExampleConfig.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,10 @@
1717
package org.springframework.boot.test.context.example;
1818

1919
import org.springframework.boot.SpringBootConfiguration;
20-
import org.springframework.boot.test.context.SpringBootConfigurationFinderTests;
20+
import org.springframework.boot.test.context.AnnotatedClassFinderTests;
2121

2222
/**
23-
* Example config used in {@link SpringBootConfigurationFinderTests}.
23+
* Example config used in {@link AnnotatedClassFinderTests}.
2424
*
2525
* @author Phillip Webb
2626
*/

spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/context/example/scan/Example.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,10 @@
1616

1717
package org.springframework.boot.test.context.example.scan;
1818

19-
import org.springframework.boot.test.context.SpringBootConfigurationFinderTests;
19+
import org.springframework.boot.test.context.AnnotatedClassFinderTests;
2020

2121
/**
22-
* Example class used in {@link SpringBootConfigurationFinderTests}.
22+
* Example class used in {@link AnnotatedClassFinderTests}.
2323
*
2424
* @author Phillip Webb
2525
*/

spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/context/example/scan/sub/SubExampleConfig.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,11 @@
1717
package org.springframework.boot.test.context.example.scan.sub;
1818

1919
import org.springframework.boot.SpringBootConfiguration;
20-
import org.springframework.boot.test.context.SpringBootConfigurationFinderTests;
20+
import org.springframework.boot.test.context.AnnotatedClassFinderTests;
2121

2222
/**
23-
* Example config used in {@link SpringBootConfigurationFinderTests}. Should not be found
24-
* since scanner should only search upwards.
23+
* Example config used in {@link AnnotatedClassFinderTests}. Should not be found since
24+
* scanner should only search upwards.
2525
*
2626
* @author Phillip Webb
2727
*/

0 commit comments

Comments
 (0)