AutoConfigurationImportSelectorTests Class — spring-boot Architecture
Architecture documentation for the AutoConfigurationImportSelectorTests class in AutoConfigurationImportSelectorTests.java from the spring-boot codebase.
Entity Profile
Relationship Graph
Source Code
core/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/AutoConfigurationImportSelectorTests.java lines 59–431
@WithResource(name = "META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports", content = """
com.example.one.FirstAutoConfiguration
com.example.two.SecondAutoConfiguration
com.example.three.ThirdAutoConfiguration
com.example.four.FourthAutoConfiguration
com.example.five.FifthAutoConfiguration
com.example.six.SixthAutoConfiguration
org.springframework.boot.autoconfigure.AutoConfigurationImportSelectorTests$SeventhAutoConfiguration
""")
class AutoConfigurationImportSelectorTests {
private final TestAutoConfigurationImportSelector importSelector = new TestAutoConfigurationImportSelector(null);
private final ConfigurableListableBeanFactory beanFactory = new DefaultListableBeanFactory();
private final MockEnvironment environment = new MockEnvironment();
private final List<AutoConfigurationImportFilter> filters = new ArrayList<>();
@BeforeEach
void setup() {
setupImportSelector(this.importSelector);
}
@Test
void importsAreSelectedWhenUsingEnableAutoConfiguration() {
String[] imports = selectImports(BasicEnableAutoConfiguration.class);
assertThat(imports).hasSameSizeAs(getAutoConfigurationClassNames());
assertThat(getLastEvent().getExclusions()).isEmpty();
}
@Test
void classExclusionsAreApplied() {
String[] imports = selectImports(EnableAutoConfigurationWithClassExclusions.class);
assertThat(imports).hasSize(getAutoConfigurationClassNames().size() - 1);
assertThat(getLastEvent().getExclusions()).contains(SeventhAutoConfiguration.class.getName());
}
@Test
void classExclusionsAreAppliedWhenUsingSpringBootApplication() {
String[] imports = selectImports(SpringBootApplicationWithClassExclusions.class);
assertThat(imports).hasSize(getAutoConfigurationClassNames().size() - 1);
assertThat(getLastEvent().getExclusions()).contains(SeventhAutoConfiguration.class.getName());
}
@Test
void classNamesExclusionsAreApplied() {
String[] imports = selectImports(EnableAutoConfigurationWithClassNameExclusions.class);
assertThat(imports).hasSize(getAutoConfigurationClassNames().size() - 1);
assertThat(getLastEvent().getExclusions()).contains("com.example.one.FirstAutoConfiguration");
}
@Test
void classNamesExclusionsAreAppliedWhenUsingSpringBootApplication() {
String[] imports = selectImports(SpringBootApplicationWithClassNameExclusions.class);
assertThat(imports).hasSize(getAutoConfigurationClassNames().size() - 1);
assertThat(getLastEvent().getExclusions()).contains("com.example.three.ThirdAutoConfiguration");
}
@Test
void propertyExclusionsAreApplied() {
this.environment.setProperty("spring.autoconfigure.exclude", "com.example.three.ThirdAutoConfiguration");
String[] imports = selectImports(BasicEnableAutoConfiguration.class);
assertThat(imports).hasSize(getAutoConfigurationClassNames().size() - 1);
assertThat(getLastEvent().getExclusions()).contains("com.example.three.ThirdAutoConfiguration");
}
@Test
void severalPropertyExclusionsAreApplied() {
this.environment.setProperty("spring.autoconfigure.exclude",
"com.example.two.SecondAutoConfiguration,com.example.four.FourthAutoConfiguration");
testSeveralPropertyExclusionsAreApplied();
}
@Test
void severalPropertyExclusionsAreAppliedWithExtraSpaces() {
this.environment.setProperty("spring.autoconfigure.exclude",
"com.example.two.SecondAutoConfiguration , com.example.four.FourthAutoConfiguration ");
testSeveralPropertyExclusionsAreApplied();
}
@Test
void severalPropertyYamlExclusionsAreApplied() {
this.environment.setProperty("spring.autoconfigure.exclude[0]", "com.example.two.SecondAutoConfiguration");
this.environment.setProperty("spring.autoconfigure.exclude[1]", "com.example.four.FourthAutoConfiguration");
testSeveralPropertyExclusionsAreApplied();
}
private void testSeveralPropertyExclusionsAreApplied() {
String[] imports = selectImports(BasicEnableAutoConfiguration.class);
assertThat(imports).hasSize(getAutoConfigurationClassNames().size() - 2);
assertThat(getLastEvent().getExclusions()).contains("com.example.two.SecondAutoConfiguration",
"com.example.four.FourthAutoConfiguration");
}
@Test
void combinedExclusionsAreApplied() {
this.environment.setProperty("spring.autoconfigure.exclude", "com.example.one.FirstAutoConfiguration");
String[] imports = selectImports(EnableAutoConfigurationWithClassAndClassNameExclusions.class);
assertThat(imports).hasSize(getAutoConfigurationClassNames().size() - 3);
assertThat(getLastEvent().getExclusions()).contains("com.example.one.FirstAutoConfiguration",
"com.example.five.FifthAutoConfiguration", SeventhAutoConfiguration.class.getName());
}
@Test
@WithTestAutoConfigurationImportsResource
@WithTestAutoConfigurationReplacementsResource
void removedExclusionsAreApplied() {
TestAutoConfigurationImportSelector importSelector = new TestAutoConfigurationImportSelector(
TestAutoConfiguration.class);
setupImportSelector(importSelector);
AnnotationMetadata metadata = AnnotationMetadata.introspect(BasicEnableAutoConfiguration.class);
assertThat(importSelector.selectImports(metadata)).contains(ReplacementAutoConfiguration.class.getName());
this.environment.setProperty("spring.autoconfigure.exclude", DeprecatedAutoConfiguration.class.getName());
assertThat(importSelector.selectImports(metadata)).doesNotContain(ReplacementAutoConfiguration.class.getName());
}
@Test
void nonAutoConfigurationClassExclusionsShouldThrowException() {
assertThatIllegalStateException()
.isThrownBy(() -> selectImports(EnableAutoConfigurationWithFaultyClassExclude.class));
}
@Test
void nonAutoConfigurationClassNameExclusionsWhenPresentOnClassPathShouldThrowException() {
assertThatIllegalStateException()
.isThrownBy(() -> selectImports(EnableAutoConfigurationWithFaultyClassNameExclude.class));
}
@Test
void nonAutoConfigurationPropertyExclusionsWhenPresentOnClassPathShouldThrowException() {
this.environment.setProperty("spring.autoconfigure.exclude",
"org.springframework.boot.autoconfigure.AutoConfigurationImportSelectorTests.TestConfiguration");
assertThatIllegalStateException().isThrownBy(() -> selectImports(BasicEnableAutoConfiguration.class));
}
@Test
void nameAndPropertyExclusionsWhenNotPresentOnClasspathShouldNotThrowException() {
this.environment.setProperty("spring.autoconfigure.exclude",
"org.springframework.boot.autoconfigure.DoesNotExist2");
selectImports(EnableAutoConfigurationWithAbsentClassNameExclude.class);
assertThat(getLastEvent().getExclusions()).containsExactlyInAnyOrder(
"org.springframework.boot.autoconfigure.DoesNotExist1",
"org.springframework.boot.autoconfigure.DoesNotExist2");
}
@Test
void filterShouldFilterImports() {
String[] defaultImports = selectImports(BasicEnableAutoConfiguration.class);
this.filters.add(new TestAutoConfigurationImportFilter(defaultImports, 1));
this.filters.add(new TestAutoConfigurationImportFilter(defaultImports, 3, 4));
String[] filtered = selectImports(BasicEnableAutoConfiguration.class);
assertThat(filtered).hasSize(defaultImports.length - 3);
assertThat(filtered).doesNotContain(defaultImports[1], defaultImports[3], defaultImports[4]);
}
@Test
void filterShouldSupportAware() {
TestAutoConfigurationImportFilter filter = new TestAutoConfigurationImportFilter(new String[] {});
this.filters.add(filter);
selectImports(BasicEnableAutoConfiguration.class);
assertThat(filter.getBeanFactory()).isEqualTo(this.beanFactory);
}
@Test
void getExclusionFilterReuseFilters() {
String[] allImports = new String[] { "com.example.A", "com.example.B", "com.example.C" };
this.filters.add(new TestAutoConfigurationImportFilter(allImports, 0));
this.filters.add(new TestAutoConfigurationImportFilter(allImports, 2));
assertThat(this.importSelector.getExclusionFilter().test("com.example.A")).isTrue();
assertThat(this.importSelector.getExclusionFilter().test("com.example.B")).isFalse();
assertThat(this.importSelector.getExclusionFilter().test("com.example.C")).isTrue();
}
@Test
@WithTestAutoConfigurationImportsResource
@WithTestAutoConfigurationReplacementsResource
void sortingConsidersReplacements() {
TestAutoConfigurationImportSelector importSelector = new TestAutoConfigurationImportSelector(
TestAutoConfiguration.class);
setupImportSelector(importSelector);
AnnotationMetadata metadata = AnnotationMetadata.introspect(BasicEnableAutoConfiguration.class);
assertThat(importSelector.selectImports(metadata)).containsExactly(
AfterDeprecatedAutoConfiguration.class.getName(), ReplacementAutoConfiguration.class.getName());
Group group = BeanUtils.instantiateClass(importSelector.getImportGroup());
((BeanFactoryAware) group).setBeanFactory(this.beanFactory);
group.process(metadata, importSelector);
Stream<Entry> imports = StreamSupport.stream(group.selectImports().spliterator(), false);
assertThat(imports.map(Entry::getImportClassName)).containsExactly(ReplacementAutoConfiguration.class.getName(),
AfterDeprecatedAutoConfiguration.class.getName());
}
private String[] selectImports(Class<?> source) {
return this.importSelector.selectImports(AnnotationMetadata.introspect(source));
}
private List<String> getAutoConfigurationClassNames() {
return ImportCandidates.load(AutoConfiguration.class, Thread.currentThread().getContextClassLoader())
.getCandidates();
}
private void setupImportSelector(TestAutoConfigurationImportSelector importSelector) {
importSelector.setBeanFactory(this.beanFactory);
importSelector.setEnvironment(this.environment);
importSelector.setResourceLoader(new DefaultResourceLoader());
importSelector.setBeanClassLoader(Thread.currentThread().getContextClassLoader());
}
private AutoConfigurationImportEvent getLastEvent() {
AutoConfigurationImportEvent result = this.importSelector.getLastEvent();
assertThat(result).isNotNull();
return result;
}
private final class TestAutoConfigurationImportSelector extends AutoConfigurationImportSelector {
private @Nullable AutoConfigurationImportEvent lastEvent;
TestAutoConfigurationImportSelector(@Nullable Class<?> autoConfigurationAnnotation) {
super(autoConfigurationAnnotation);
}
@Override
protected List<AutoConfigurationImportFilter> getAutoConfigurationImportFilters() {
return AutoConfigurationImportSelectorTests.this.filters;
}
@Override
protected List<AutoConfigurationImportListener> getAutoConfigurationImportListeners() {
return Collections.singletonList((event) -> this.lastEvent = event);
}
@Nullable AutoConfigurationImportEvent getLastEvent() {
return this.lastEvent;
}
}
static class TestAutoConfigurationImportFilter implements AutoConfigurationImportFilter, BeanFactoryAware {
private final Set<String> nonMatching = new HashSet<>();
@SuppressWarnings("NullAway.Init")
private BeanFactory beanFactory;
TestAutoConfigurationImportFilter(String[] configurations, int... nonMatching) {
for (int i : nonMatching) {
this.nonMatching.add(configurations[i]);
}
}
@Override
public boolean[] match(@Nullable String[] autoConfigurationClasses,
AutoConfigurationMetadata autoConfigurationMetadata) {
boolean[] result = new boolean[autoConfigurationClasses.length];
for (int i = 0; i < result.length; i++) {
result[i] = !this.nonMatching.contains(autoConfigurationClasses[i]);
}
return result;
}
@Override
public void setBeanFactory(BeanFactory beanFactory) {
this.beanFactory = beanFactory;
}
BeanFactory getBeanFactory() {
return this.beanFactory;
}
}
@Configuration(proxyBeanMethods = false)
private final class TestConfiguration {
}
@EnableAutoConfiguration
private final class BasicEnableAutoConfiguration {
}
@EnableAutoConfiguration(exclude = SeventhAutoConfiguration.class)
private final class EnableAutoConfigurationWithClassExclusions {
}
@SpringBootApplication(exclude = SeventhAutoConfiguration.class)
private final class SpringBootApplicationWithClassExclusions {
}
@EnableAutoConfiguration(excludeName = "com.example.one.FirstAutoConfiguration")
private final class EnableAutoConfigurationWithClassNameExclusions {
}
@EnableAutoConfiguration(exclude = SeventhAutoConfiguration.class,
excludeName = "com.example.five.FifthAutoConfiguration")
private final class EnableAutoConfigurationWithClassAndClassNameExclusions {
}
@EnableAutoConfiguration(exclude = TestConfiguration.class)
private final class EnableAutoConfigurationWithFaultyClassExclude {
}
@EnableAutoConfiguration(
excludeName = "org.springframework.boot.autoconfigure.AutoConfigurationImportSelectorTests.TestConfiguration")
private final class EnableAutoConfigurationWithFaultyClassNameExclude {
}
@EnableAutoConfiguration(excludeName = "org.springframework.boot.autoconfigure.DoesNotExist1")
private final class EnableAutoConfigurationWithAbsentClassNameExclude {
}
@SpringBootApplication(excludeName = "com.example.three.ThirdAutoConfiguration")
private final class SpringBootApplicationWithClassNameExclusions {
}
static class DeprecatedAutoConfiguration {
}
static class ReplacementAutoConfiguration {
}
@AutoConfigureAfter(DeprecatedAutoConfiguration.class)
static class AfterDeprecatedAutoConfiguration {
}
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@interface TestAutoConfiguration {
}
@AutoConfiguration
public static final class SeventhAutoConfiguration {
}
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@WithResource(
name = "META-INF/spring/org.springframework.boot.autoconfigure.AutoConfigurationImportSelectorTests$TestAutoConfiguration.imports",
content = """
org.springframework.boot.autoconfigure.AutoConfigurationImportSelectorTests$AfterDeprecatedAutoConfiguration
org.springframework.boot.autoconfigure.AutoConfigurationImportSelectorTests$ReplacementAutoConfiguration
""")
@interface WithTestAutoConfigurationImportsResource {
}
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@WithResource(
name = "META-INF/spring/org.springframework.boot.autoconfigure.AutoConfigurationImportSelectorTests$TestAutoConfiguration.replacements",
content = """
org.springframework.boot.autoconfigure.AutoConfigurationImportSelectorTests$DeprecatedAutoConfiguration=\
org.springframework.boot.autoconfigure.AutoConfigurationImportSelectorTests$ReplacementAutoConfiguration
""")
@interface WithTestAutoConfigurationReplacementsResource {
}
}
Domain
Source
Analyze Your Own Codebase
Get architecture documentation, dependency graphs, and domain analysis for your codebase in minutes.
Try Supermodel Free