This commit is contained in:
Phillip Webb 2024-09-09 12:47:39 -07:00
parent 083ac67d13
commit ddd0d898c2
4 changed files with 39 additions and 31 deletions

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2023 the original author or authors.
* Copyright 2012-2024 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.
@ -63,8 +63,8 @@ public class AutoConfigurationExcludeFilter implements TypeFilter, BeanClassLoad
protected List<String> getAutoConfigurations() {
if (this.autoConfigurations == null) {
this.autoConfigurations = ImportCandidates.load(AutoConfiguration.class, this.beanClassLoader)
.getCandidates();
ImportCandidates importCandidates = ImportCandidates.load(AutoConfiguration.class, this.beanClassLoader);
this.autoConfigurations = importCandidates.getCandidates();
}
return this.autoConfigurations;
}

View File

@ -76,6 +76,8 @@ import org.springframework.util.StringUtils;
public class AutoConfigurationImportSelector implements DeferredImportSelector, BeanClassLoaderAware,
ResourceLoaderAware, BeanFactoryAware, EnvironmentAware, Ordered {
static final int ORDER = Ordered.LOWEST_PRECEDENCE - 1;
private static final AutoConfigurationEntry EMPTY_ENTRY = new AutoConfigurationEntry();
private static final String[] NO_IMPORTS = {};
@ -92,7 +94,7 @@ public class AutoConfigurationImportSelector implements DeferredImportSelector,
private ResourceLoader resourceLoader;
private ConfigurationClassFilter configurationClassFilter;
private volatile ConfigurationClassFilter configurationClassFilter;
@Override
public String[] selectImports(AnnotationMetadata annotationMetadata) {
@ -177,8 +179,8 @@ public class AutoConfigurationImportSelector implements DeferredImportSelector,
* @return a list of candidate configurations
*/
protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {
List<String> configurations = ImportCandidates.load(AutoConfiguration.class, getBeanClassLoader())
.getCandidates();
ImportCandidates importCandidates = ImportCandidates.load(AutoConfiguration.class, getBeanClassLoader());
List<String> configurations = importCandidates.getCandidates();
Assert.notEmpty(configurations,
"No auto configuration classes found in "
+ "META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports. If you "
@ -254,14 +256,16 @@ public class AutoConfigurationImportSelector implements DeferredImportSelector,
}
private ConfigurationClassFilter getConfigurationClassFilter() {
if (this.configurationClassFilter == null) {
ConfigurationClassFilter configurationClassFilter = this.configurationClassFilter;
if (configurationClassFilter == null) {
List<AutoConfigurationImportFilter> filters = getAutoConfigurationImportFilters();
for (AutoConfigurationImportFilter filter : filters) {
invokeAwareMethods(filter);
}
this.configurationClassFilter = new ConfigurationClassFilter(this.beanClassLoader, filters);
configurationClassFilter = new ConfigurationClassFilter(this.beanClassLoader, filters);
this.configurationClassFilter = configurationClassFilter;
}
return this.configurationClassFilter;
return configurationClassFilter;
}
protected final <T> List<T> removeDuplicates(List<T> list) {
@ -344,7 +348,7 @@ public class AutoConfigurationImportSelector implements DeferredImportSelector,
@Override
public int getOrder() {
return Ordered.LOWEST_PRECEDENCE - 1;
return ORDER;
}
private static class ConfigurationClassFilter {

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2023 the original author or authors.
* Copyright 2012-2024 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.
@ -39,7 +39,7 @@ public class AutoConfigurations extends Configurations implements Ordered {
private static final AutoConfigurationSorter SORTER = new AutoConfigurationSorter(new SimpleMetadataReaderFactory(),
null);
private static final Ordered ORDER = new AutoConfigurationImportSelector();
private static final int ORDER = AutoConfigurationImportSelector.ORDER;
protected AutoConfigurations(Collection<Class<?>> classes) {
super(classes);
@ -56,7 +56,7 @@ public class AutoConfigurations extends Configurations implements Ordered {
@Override
public int getOrder() {
return ORDER.getOrder();
return ORDER;
}
@Override

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2023 the original author or authors.
* Copyright 2012-2024 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.
@ -97,19 +97,19 @@ class AutoConfigurationSorterTests {
@Test
void byOrderAnnotation() {
List<String> actual = this.sorter.getInPriorityOrder(Arrays.asList(LOWEST, HIGHEST, DEFAULT));
List<String> actual = getInPriorityOrder(LOWEST, HIGHEST, DEFAULT);
assertThat(actual).containsExactly(HIGHEST, DEFAULT, LOWEST);
}
@Test
void byAutoConfigureAfter() {
List<String> actual = this.sorter.getInPriorityOrder(Arrays.asList(A, B, C));
List<String> actual = getInPriorityOrder(A, B, C);
assertThat(actual).containsExactly(C, B, A);
}
@Test
void byAutoConfigureAfterAliasFor() {
List<String> actual = this.sorter.getInPriorityOrder(Arrays.asList(A3, B2, C));
List<String> actual = getInPriorityOrder(A3, B2, C);
assertThat(actual).containsExactly(C, B2, A3);
}
@ -118,19 +118,19 @@ class AutoConfigurationSorterTests {
MetadataReaderFactory readerFactory = new CachingMetadataReaderFactory();
this.autoConfigurationMetadata = getAutoConfigurationMetadata(A3, B2, C);
this.sorter = new AutoConfigurationSorter(readerFactory, this.autoConfigurationMetadata);
List<String> actual = this.sorter.getInPriorityOrder(Arrays.asList(A3, B2, C));
List<String> actual = getInPriorityOrder(A3, B2, C);
assertThat(actual).containsExactly(C, B2, A3);
}
@Test
void byAutoConfigureBefore() {
List<String> actual = this.sorter.getInPriorityOrder(Arrays.asList(X, Y, Z));
List<String> actual = getInPriorityOrder(X, Y, Z);
assertThat(actual).containsExactly(Z, Y, X);
}
@Test
void byAutoConfigureBeforeAliasFor() {
List<String> actual = this.sorter.getInPriorityOrder(Arrays.asList(X, Y2, Z2));
List<String> actual = getInPriorityOrder(X, Y2, Z2);
assertThat(actual).containsExactly(Z2, Y2, X);
}
@ -139,44 +139,44 @@ class AutoConfigurationSorterTests {
MetadataReaderFactory readerFactory = new CachingMetadataReaderFactory();
this.autoConfigurationMetadata = getAutoConfigurationMetadata(X, Y2, Z2);
this.sorter = new AutoConfigurationSorter(readerFactory, this.autoConfigurationMetadata);
List<String> actual = this.sorter.getInPriorityOrder(Arrays.asList(X, Y2, Z2));
List<String> actual = getInPriorityOrder(X, Y2, Z2);
assertThat(actual).containsExactly(Z2, Y2, X);
}
@Test
void byAutoConfigureAfterDoubles() {
List<String> actual = this.sorter.getInPriorityOrder(Arrays.asList(A, B, C, E));
List<String> actual = getInPriorityOrder(A, B, C, E);
assertThat(actual).containsExactly(C, E, B, A);
}
@Test
void byAutoConfigureMixedBeforeAndAfter() {
List<String> actual = this.sorter.getInPriorityOrder(Arrays.asList(A, B, C, W, X));
List<String> actual = getInPriorityOrder(A, B, C, W, X);
assertThat(actual).containsExactly(C, W, B, A, X);
}
@Test
void byAutoConfigureMixedBeforeAndAfterWithClassNames() {
List<String> actual = this.sorter.getInPriorityOrder(Arrays.asList(A2, B, C, W2, X));
List<String> actual = getInPriorityOrder(A2, B, C, W2, X);
assertThat(actual).containsExactly(C, W2, B, A2, X);
}
@Test
void byAutoConfigureMixedBeforeAndAfterWithDifferentInputOrder() {
List<String> actual = this.sorter.getInPriorityOrder(Arrays.asList(W, X, A, B, C));
List<String> actual = getInPriorityOrder(W, X, A, B, C);
assertThat(actual).containsExactly(C, W, B, A, X);
}
@Test
void byAutoConfigureAfterWithMissing() {
List<String> actual = this.sorter.getInPriorityOrder(Arrays.asList(A, B));
List<String> actual = getInPriorityOrder(A, B);
assertThat(actual).containsExactly(B, A);
}
@Test
void byAutoConfigureAfterWithCycle() {
this.sorter = new AutoConfigurationSorter(new CachingMetadataReaderFactory(), this.autoConfigurationMetadata);
assertThatIllegalStateException().isThrownBy(() -> this.sorter.getInPriorityOrder(Arrays.asList(A, B, C, D)))
assertThatIllegalStateException().isThrownBy(() -> getInPriorityOrder(A, B, C, D))
.withMessageContaining("AutoConfigure cycle detected");
}
@ -185,7 +185,7 @@ class AutoConfigurationSorterTests {
MetadataReaderFactory readerFactory = new SkipCycleMetadataReaderFactory();
this.autoConfigurationMetadata = getAutoConfigurationMetadata(A2, B, C, W2, X);
this.sorter = new AutoConfigurationSorter(readerFactory, this.autoConfigurationMetadata);
List<String> actual = this.sorter.getInPriorityOrder(Arrays.asList(A2, B, C, W2, X));
List<String> actual = getInPriorityOrder(A2, B, C, W2, X);
assertThat(actual).containsExactly(C, W2, B, A2, X);
}
@ -194,7 +194,7 @@ class AutoConfigurationSorterTests {
MetadataReaderFactory readerFactory = new SkipCycleMetadataReaderFactory();
this.autoConfigurationMetadata = getAutoConfigurationMetadata(A, B, E);
this.sorter = new AutoConfigurationSorter(readerFactory, this.autoConfigurationMetadata);
List<String> actual = this.sorter.getInPriorityOrder(Arrays.asList(A, E));
List<String> actual = getInPriorityOrder(A, E);
assertThat(actual).containsExactly(E, A);
}
@ -203,7 +203,7 @@ class AutoConfigurationSorterTests {
MetadataReaderFactory readerFactory = new CachingMetadataReaderFactory();
this.autoConfigurationMetadata = getAutoConfigurationMetadata(A, B, D);
this.sorter = new AutoConfigurationSorter(readerFactory, this.autoConfigurationMetadata);
assertThatIllegalStateException().isThrownBy(() -> this.sorter.getInPriorityOrder(Arrays.asList(D, B)))
assertThatIllegalStateException().isThrownBy(() -> getInPriorityOrder(D, B))
.withMessageContaining("AutoConfigure cycle detected");
}
@ -214,10 +214,14 @@ class AutoConfigurationSorterTests {
String oa2 = OrderAutoConfigureASeedY2.class.getName();
String oa3 = OrderAutoConfigureASeedA3.class.getName();
String oa4 = OrderAutoConfigureAutoConfigureASeedG4.class.getName();
List<String> actual = this.sorter.getInPriorityOrder(Arrays.asList(oa4, oa3, oa2, oa1, oa));
List<String> actual = getInPriorityOrder(oa4, oa3, oa2, oa1, oa);
assertThat(actual).containsExactly(oa1, oa2, oa3, oa4, oa);
}
private List<String> getInPriorityOrder(String... classNames) {
return this.sorter.getInPriorityOrder(Arrays.asList(classNames));
}
private AutoConfigurationMetadata getAutoConfigurationMetadata(String... classNames) throws Exception {
Properties properties = new Properties();
for (String className : classNames) {