Remove support for locating imports using spring.factories

With this commit, loading `@AutoConfiguration`,
`@ImportAutoConfiguration`, and `@ManagementContextConfiguration`
classes is supported with `.imports` files only. Support for loading
these classes with `spring.factories` is removed.

Closes gh-29699
This commit is contained in:
Scott Frederick
2022-09-21 15:56:35 -05:00
parent 6b8575b001
commit 08022ba86e
9 changed files with 35 additions and 100 deletions

View File

@@ -30,16 +30,13 @@ import org.springframework.context.annotation.AnnotationConfigApplicationContext
import org.springframework.context.annotation.Conditional;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.AliasFor;
import org.springframework.core.io.support.SpringFactoriesLoader;
/**
* Indicates that a class provides configuration that can be automatically applied by
* Spring Boot. Auto-configuration classes are regular
* {@link Configuration @Configuration} with the exception that
* {@literal Configuration#proxyBeanMethods() proxyBeanMethods} is always {@code false}.
* <p>
* They are located using {@link ImportCandidates} and the {@link SpringFactoriesLoader}
* mechanism (keyed against {@link EnableAutoConfiguration}).
* They are located using {@link ImportCandidates}.
* <p>
* Generally auto-configuration classes are marked as {@link Conditional @Conditional}
* (most often using {@link ConditionalOnClass @ConditionalOnClass} and

View File

@@ -17,13 +17,11 @@
package org.springframework.boot.autoconfigure;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import org.springframework.beans.factory.BeanClassLoaderAware;
import org.springframework.boot.context.annotation.ImportCandidates;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.support.SpringFactoriesLoader;
import org.springframework.core.type.classreading.MetadataReader;
import org.springframework.core.type.classreading.MetadataReaderFactory;
import org.springframework.core.type.filter.TypeFilter;
@@ -32,6 +30,7 @@ import org.springframework.core.type.filter.TypeFilter;
* A {@link TypeFilter} implementation that matches registered auto-configuration classes.
*
* @author Stephane Nicoll
* @author Scott Frederick
* @since 1.5.0
*/
public class AutoConfigurationExcludeFilter implements TypeFilter, BeanClassLoaderAware {
@@ -64,11 +63,8 @@ public class AutoConfigurationExcludeFilter implements TypeFilter, BeanClassLoad
protected List<String> getAutoConfigurations() {
if (this.autoConfigurations == null) {
@SuppressWarnings("deprecation")
List<String> autoConfigurations = new ArrayList<>(
SpringFactoriesLoader.loadFactoryNames(EnableAutoConfiguration.class, this.beanClassLoader));
ImportCandidates.load(AutoConfiguration.class, this.beanClassLoader).forEach(autoConfigurations::add);
this.autoConfigurations = autoConfigurations;
this.autoConfigurations = ImportCandidates.load(AutoConfiguration.class, this.beanClassLoader)
.getCandidates();
}
return this.autoConfigurations;
}

View File

@@ -69,6 +69,7 @@ import org.springframework.util.StringUtils;
* @author Stephane Nicoll
* @author Madhura Bhave
* @author Moritz Halbritter
* @author Scott Frederick
* @since 1.3.0
* @see EnableAutoConfiguration
*/
@@ -168,36 +169,23 @@ public class AutoConfigurationImportSelector implements DeferredImportSelector,
}
/**
* Return the auto-configuration class names that should be considered. By default
* this method will load candidates using {@link ImportCandidates} with
* {@link #getSpringFactoriesLoaderFactoryClass()}. For backward compatible reasons it
* will also consider {@link SpringFactoriesLoader} with
* {@link #getSpringFactoriesLoaderFactoryClass()}.
* Return the auto-configuration class names that should be considered. By default,
* this method will load candidates using {@link ImportCandidates}.
* @param metadata the source metadata
* @param attributes the {@link #getAttributes(AnnotationMetadata) annotation
* attributes}
* @return a list of candidate configurations
*/
protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {
@SuppressWarnings("deprecation")
List<String> configurations = new ArrayList<>(
SpringFactoriesLoader.loadFactoryNames(getSpringFactoriesLoaderFactoryClass(), getBeanClassLoader()));
ImportCandidates.load(AutoConfiguration.class, getBeanClassLoader()).forEach(configurations::add);
List<String> configurations = ImportCandidates.load(AutoConfiguration.class, getBeanClassLoader())
.getCandidates();
Assert.notEmpty(configurations,
"No auto configuration classes found in META-INF/spring.factories nor in META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports. If you "
"No auto configuration classes found in "
+ "META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports. If you "
+ "are using a custom packaging, make sure that file is correct.");
return configurations;
}
/**
* Return the class used by {@link SpringFactoriesLoader} to load configuration
* candidates.
* @return the factory class
*/
protected Class<?> getSpringFactoriesLoaderFactoryClass() {
return EnableAutoConfiguration.class;
}
private void checkExcludedClasses(List<String> configurations, Set<String> exclusions) {
List<String> invalidExcludes = new ArrayList<>(exclusions.size());
for (String exclusion : exclusions) {

View File

@@ -32,7 +32,6 @@ import org.springframework.boot.web.servlet.server.ServletWebServerFactory;
import org.springframework.context.annotation.Conditional;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.core.io.support.SpringFactoriesLoader;
/**
* Enable auto-configuration of the Spring Application Context, attempting to guess and
@@ -61,9 +60,8 @@ import org.springframework.core.io.support.SpringFactoriesLoader;
* and classes can be searched.
* <p>
* Auto-configuration classes are regular Spring {@link Configuration @Configuration}
* beans. They are located using {@link ImportCandidates} and the
* {@link SpringFactoriesLoader} mechanism (keyed against this class). Generally
* auto-configuration beans are {@link Conditional @Conditional} beans (most often using
* beans. They are located using {@link ImportCandidates}. Generally auto-configuration
* beans are {@link Conditional @Conditional} beans (most often using
* {@link ConditionalOnClass @ConditionalOnClass} and
* {@link ConditionalOnMissingBean @ConditionalOnMissingBean} annotations).
*

View File

@@ -32,7 +32,6 @@ import org.springframework.boot.context.annotation.ImportCandidates;
import org.springframework.core.annotation.AnnotatedElementUtils;
import org.springframework.core.annotation.AnnotationAttributes;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.core.io.support.SpringFactoriesLoader;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.util.ClassUtils;
import org.springframework.util.LinkedMultiValueMap;
@@ -46,6 +45,7 @@ import org.springframework.util.ObjectUtils;
* @author Phillip Webb
* @author Andy Wilkinson
* @author Moritz Halbritter
* @author Scott Frederick
*/
class ImportAutoConfigurationImportSelector extends AutoConfigurationImportSelector implements DeterminableImports {
@@ -96,11 +96,7 @@ class ImportAutoConfigurationImportSelector extends AutoConfigurationImportSelec
}
protected Collection<String> loadFactoryNames(Class<?> source) {
@SuppressWarnings("deprecation")
List<String> factoryNames = new ArrayList<>(
SpringFactoriesLoader.loadFactoryNames(source, getBeanClassLoader()));
ImportCandidates.load(source, getBeanClassLoader()).forEach(factoryNames::add);
return factoryNames;
return ImportCandidates.load(source, getBeanClassLoader()).getCandidates();
}
@Override

View File

@@ -213,10 +213,7 @@ class AutoConfigurationImportSelectorTests {
}
private List<String> getAutoConfigurationClassNames() {
List<String> autoConfigurationClassNames = new ArrayList<>();
ImportCandidates.load(AutoConfiguration.class, getClass().getClassLoader())
.forEach(autoConfigurationClassNames::add);
return autoConfigurationClassNames;
return ImportCandidates.load(AutoConfiguration.class, getClass().getClassLoader()).getCandidates();
}
private class TestAutoConfigurationImportSelector extends AutoConfigurationImportSelector {