mirror of
https://github.com/spring-projects/spring-boot.git
synced 2024-07-05 00:56:58 +08:00
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:
parent
6b8575b001
commit
08022ba86e
@ -23,15 +23,13 @@ import java.io.FileReader;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.Reader;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.gradle.api.DefaultTask;
|
||||
import org.gradle.api.Task;
|
||||
@ -43,13 +41,13 @@ import org.gradle.api.tasks.TaskAction;
|
||||
import org.springframework.asm.ClassReader;
|
||||
import org.springframework.asm.Opcodes;
|
||||
import org.springframework.core.CollectionFactory;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* A {@link Task} for generating metadata describing a project's auto-configuration
|
||||
* classes.
|
||||
*
|
||||
* @author Andy Wilkinson
|
||||
* @author Scott Frederick
|
||||
*/
|
||||
public class AutoConfigurationMetadata extends DefaultTask {
|
||||
|
||||
@ -60,10 +58,6 @@ public class AutoConfigurationMetadata extends DefaultTask {
|
||||
private File outputFile;
|
||||
|
||||
public AutoConfigurationMetadata() {
|
||||
getInputs()
|
||||
.file((Callable<File>) () -> new File(this.sourceSet.getOutput().getResourcesDir(),
|
||||
"META-INF/spring.factories"))
|
||||
.withPathSensitivity(PathSensitivity.RELATIVE).withPropertyName("spring.factories");
|
||||
getInputs()
|
||||
.file((Callable<File>) () -> new File(this.sourceSet.getOutput().getResourcesDir(),
|
||||
"META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports"))
|
||||
@ -99,9 +93,7 @@ public class AutoConfigurationMetadata extends DefaultTask {
|
||||
|
||||
private Properties readAutoConfiguration() throws IOException {
|
||||
Properties autoConfiguration = CollectionFactory.createSortedProperties(true);
|
||||
Set<String> classNames = new LinkedHashSet<>();
|
||||
classNames.addAll(readSpringFactories());
|
||||
classNames.addAll(readAutoConfigurationsFile());
|
||||
List<String> classNames = readAutoConfigurationsFile();
|
||||
Set<String> publicClassNames = new LinkedHashSet<>();
|
||||
for (String className : classNames) {
|
||||
File classFile = findClassFile(className);
|
||||
@ -120,21 +112,6 @@ public class AutoConfigurationMetadata extends DefaultTask {
|
||||
return autoConfiguration;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads auto-configurations from META-INF/spring.factories.
|
||||
* @return auto-configurations
|
||||
*/
|
||||
private Set<String> readSpringFactories() throws IOException {
|
||||
File file = new File(this.sourceSet.getOutput().getResourcesDir(), "META-INF/spring.factories");
|
||||
if (!file.exists()) {
|
||||
return Collections.emptySet();
|
||||
}
|
||||
Properties springFactories = readSpringFactories(file);
|
||||
String enableAutoConfiguration = springFactories
|
||||
.getProperty("org.springframework.boot.autoconfigure.EnableAutoConfiguration");
|
||||
return StringUtils.commaDelimitedListToSet(enableAutoConfiguration);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads auto-configurations from
|
||||
* META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports.
|
||||
@ -146,29 +123,18 @@ public class AutoConfigurationMetadata extends DefaultTask {
|
||||
if (!file.exists()) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
// Nearly identical copy of
|
||||
// org.springframework.boot.context.annotation.ImportCandidates.load
|
||||
try (BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(file)))) {
|
||||
List<String> autoConfigurations = new ArrayList<>();
|
||||
String line;
|
||||
while ((line = reader.readLine()) != null) {
|
||||
line = stripComment(line);
|
||||
line = line.trim();
|
||||
if (line.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
autoConfigurations.add(line);
|
||||
}
|
||||
return autoConfigurations;
|
||||
try (BufferedReader reader = new BufferedReader(new FileReader(file))) {
|
||||
return reader.lines().map(this::stripComment).filter((line) -> !line.isEmpty())
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
}
|
||||
|
||||
private String stripComment(String line) {
|
||||
int commentStart = line.indexOf(COMMENT_START);
|
||||
if (commentStart == -1) {
|
||||
return line;
|
||||
return line.trim();
|
||||
}
|
||||
return line.substring(0, commentStart);
|
||||
return line.substring(0, commentStart).trim();
|
||||
}
|
||||
|
||||
private File findClassFile(String className) {
|
||||
@ -182,12 +148,4 @@ public class AutoConfigurationMetadata extends DefaultTask {
|
||||
return null;
|
||||
}
|
||||
|
||||
private Properties readSpringFactories(File file) throws IOException {
|
||||
Properties springFactories = new Properties();
|
||||
try (Reader in = new FileReader(file)) {
|
||||
springFactories.load(in);
|
||||
}
|
||||
return springFactories;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -29,7 +29,6 @@ import org.springframework.context.annotation.DeferredImportSelector;
|
||||
import org.springframework.core.OrderComparator;
|
||||
import org.springframework.core.Ordered;
|
||||
import org.springframework.core.annotation.Order;
|
||||
import org.springframework.core.io.support.SpringFactoriesLoader;
|
||||
import org.springframework.core.type.AnnotationMetadata;
|
||||
import org.springframework.core.type.classreading.MetadataReader;
|
||||
import org.springframework.core.type.classreading.SimpleMetadataReaderFactory;
|
||||
@ -44,6 +43,7 @@ import org.springframework.util.StringUtils;
|
||||
* @author Phillip Webb
|
||||
* @author Andy Wilkinson
|
||||
* @author Moritz Halbritter
|
||||
* @author Scott Frederick
|
||||
* @see ManagementContextConfiguration
|
||||
* @see ImportCandidates
|
||||
*/
|
||||
@ -90,11 +90,7 @@ class ManagementContextConfigurationImportSelector implements DeferredImportSele
|
||||
}
|
||||
|
||||
protected List<String> loadFactoryNames() {
|
||||
@SuppressWarnings("deprecation")
|
||||
List<String> factoryNames = new ArrayList<>(
|
||||
SpringFactoriesLoader.loadFactoryNames(ManagementContextConfiguration.class, this.classLoader));
|
||||
ImportCandidates.load(ManagementContextConfiguration.class, this.classLoader).forEach(factoryNames::add);
|
||||
return factoryNames;
|
||||
return ImportCandidates.load(ManagementContextConfiguration.class, this.classLoader).getCandidates();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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) {
|
||||
|
@ -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).
|
||||
*
|
||||
|
@ -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
|
||||
|
@ -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 {
|
||||
|
@ -37,6 +37,7 @@ import org.springframework.util.Assert;
|
||||
* candidates.
|
||||
*
|
||||
* @author Moritz Halbritter
|
||||
* @author Scott Frederick
|
||||
* @since 2.7.0
|
||||
*/
|
||||
public final class ImportCandidates implements Iterable<String> {
|
||||
@ -57,6 +58,14 @@ public final class ImportCandidates implements Iterable<String> {
|
||||
return this.candidates.iterator();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the list of loaded import candidates.
|
||||
* @return the list of import candidates
|
||||
*/
|
||||
public List<String> getCandidates() {
|
||||
return this.candidates;
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the names of import candidates from the classpath.
|
||||
*
|
||||
|
Loading…
Reference in New Issue
Block a user