From d7b229d3c72b153f879babf754c9a6351d517114 Mon Sep 17 00:00:00 2001 From: Moritz Halbritter Date: Mon, 21 Feb 2022 09:44:30 +0100 Subject: [PATCH] Rename AutoConfigurationLoader to ImportCandidates Move the class to a more suitable package, and load the files from META-INF/spring/.imports See gh-29872 --- .../AutoConfigurationMetadata.java | 8 +-- .../test/autoconfigure/TestSliceMetadata.java | 9 ++- ...t.autoconfigure.AutoConfiguration.imports} | 0 .../boot/autoconfigure/AutoConfiguration.java | 6 +- .../AutoConfigurationExcludeFilter.java | 7 +-- .../AutoConfigurationImportSelector.java | 10 ++-- .../EnableAutoConfiguration.java | 3 +- .../ImportAutoConfiguration.java | 4 +- ...ImportAutoConfigurationImportSelector.java | 9 +-- ...t.autoconfigure.AutoConfiguration.imports} | 0 .../AutoConfigurationImportSelectorTests.java | 6 +- ...t.autoconfigure.AutoConfiguration.imports} | 0 .../developing-auto-configuration.adoc | 4 +- .../src/docs/asciidoc/features/testing.adoc | 4 +- ...configure.core.AutoConfigureCache.imports} | 0 ...sandra.AutoConfigureDataCassandra.imports} | 0 ...e.data.jdbc.AutoConfigureDataJdbc.imports} | 0 ...e.data.ldap.AutoConfigureDataLdap.imports} | 0 ...data.mongo.AutoConfigureDataMongo.imports} | 0 ...data.neo4j.AutoConfigureDataNeo4j.imports} | 0 ...data.r2dbc.AutoConfigureDataR2dbc.imports} | 0 ...data.redis.AutoConfigureDataRedis.imports} | 0 ...gure.graphql.AutoConfigureGraphQl.imports} | 0 ...tester.AutoConfigureGraphQlTester.imports} | 0 ...ter.AutoConfigureWebGraphQlTester.imports} | 0 ...oconfigure.jdbc.AutoConfigureJdbc.imports} | 0 ...re.jdbc.AutoConfigureTestDatabase.imports} | 0 ...oconfigure.jooq.AutoConfigureJooq.imports} | 0 ...oconfigure.json.AutoConfigureJson.imports} | 0 ...ure.json.AutoConfigureJsonTesters.imports} | 0 ...gure.orm.jpa.AutoConfigureDataJpa.imports} | 0 ...pa.AutoConfigureTestEntityManager.imports} | 0 ...re.restdocs.AutoConfigureRestDocs.imports} | 0 ...utoConfigureMockRestServiceServer.imports} | 0 ...web.client.AutoConfigureWebClient.imports} | 0 ...web.reactive.AutoConfigureWebFlux.imports} | 0 ...active.AutoConfigureWebTestClient.imports} | 0 ....web.servlet.AutoConfigureMockMvc.imports} | 0 ...e.web.servlet.AutoConfigureWebMvc.imports} | 0 ...AutoConfigureMockWebServiceServer.imports} | 0 ...ent.AutoConfigureWebServiceClient.imports} | 0 ...AutoConfigureMockWebServiceClient.imports} | 0 ...ver.AutoConfigureWebServiceServer.imports} | 0 .../context/annotation/ImportCandidates.java} | 57 ++++++++++++------- ...portCandidatesTest$TestAnnotation.imports} | 2 +- .../annotation/ImportCandidatesTest.java} | 23 ++------ ...t.autoconfigure.AutoConfiguration.imports} | 0 ...t.autoconfigure.AutoConfiguration.imports} | 0 48 files changed, 84 insertions(+), 68 deletions(-) rename spring-boot-project/spring-boot-actuator-autoconfigure/src/main/resources/META-INF/{spring-boot/org.springframework.boot.autoconfigure.AutoConfiguration => spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports} (100%) rename spring-boot-project/spring-boot-autoconfigure/src/main/resources/META-INF/{spring-boot/org.springframework.boot.autoconfigure.AutoConfiguration => spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports} (100%) rename spring-boot-project/spring-boot-devtools/src/main/resources/META-INF/{spring-boot/org.springframework.boot.autoconfigure.AutoConfiguration => spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports} (100%) rename spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/{spring-boot/org.springframework.boot.test.autoconfigure.core.AutoConfigureCache => spring/org.springframework.boot.test.autoconfigure.core.AutoConfigureCache.imports} (100%) rename spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/{spring-boot/org.springframework.boot.test.autoconfigure.data.cassandra.AutoConfigureDataCassandra => spring/org.springframework.boot.test.autoconfigure.data.cassandra.AutoConfigureDataCassandra.imports} (100%) rename spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/{spring-boot/org.springframework.boot.test.autoconfigure.data.jdbc.AutoConfigureDataJdbc => spring/org.springframework.boot.test.autoconfigure.data.jdbc.AutoConfigureDataJdbc.imports} (100%) rename spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/{spring-boot/org.springframework.boot.test.autoconfigure.data.ldap.AutoConfigureDataLdap => spring/org.springframework.boot.test.autoconfigure.data.ldap.AutoConfigureDataLdap.imports} (100%) rename spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/{spring-boot/org.springframework.boot.test.autoconfigure.data.mongo.AutoConfigureDataMongo => spring/org.springframework.boot.test.autoconfigure.data.mongo.AutoConfigureDataMongo.imports} (100%) rename spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/{spring-boot/org.springframework.boot.test.autoconfigure.data.neo4j.AutoConfigureDataNeo4j => spring/org.springframework.boot.test.autoconfigure.data.neo4j.AutoConfigureDataNeo4j.imports} (100%) rename spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/{spring-boot/org.springframework.boot.test.autoconfigure.data.r2dbc.AutoConfigureDataR2dbc => spring/org.springframework.boot.test.autoconfigure.data.r2dbc.AutoConfigureDataR2dbc.imports} (100%) rename spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/{spring-boot/org.springframework.boot.test.autoconfigure.data.redis.AutoConfigureDataRedis => spring/org.springframework.boot.test.autoconfigure.data.redis.AutoConfigureDataRedis.imports} (100%) rename spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/{spring-boot/org.springframework.boot.test.autoconfigure.graphql.AutoConfigureGraphQl => spring/org.springframework.boot.test.autoconfigure.graphql.AutoConfigureGraphQl.imports} (100%) rename spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/{spring-boot/org.springframework.boot.test.autoconfigure.graphql.tester.AutoConfigureGraphQlTester => spring/org.springframework.boot.test.autoconfigure.graphql.tester.AutoConfigureGraphQlTester.imports} (100%) rename spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/{spring-boot/org.springframework.boot.test.autoconfigure.graphql.tester.AutoConfigureWebGraphQlTester => spring/org.springframework.boot.test.autoconfigure.graphql.tester.AutoConfigureWebGraphQlTester.imports} (100%) rename spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/{spring-boot/org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureJdbc => spring/org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureJdbc.imports} (100%) rename spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/{spring-boot/org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase => spring/org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase.imports} (100%) rename spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/{spring-boot/org.springframework.boot.test.autoconfigure.jooq.AutoConfigureJooq => spring/org.springframework.boot.test.autoconfigure.jooq.AutoConfigureJooq.imports} (100%) rename spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/{spring-boot/org.springframework.boot.test.autoconfigure.json.AutoConfigureJson => spring/org.springframework.boot.test.autoconfigure.json.AutoConfigureJson.imports} (100%) rename spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/{spring-boot/org.springframework.boot.test.autoconfigure.json.AutoConfigureJsonTesters => spring/org.springframework.boot.test.autoconfigure.json.AutoConfigureJsonTesters.imports} (100%) rename spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/{spring-boot/org.springframework.boot.test.autoconfigure.orm.jpa.AutoConfigureDataJpa => spring/org.springframework.boot.test.autoconfigure.orm.jpa.AutoConfigureDataJpa.imports} (100%) rename spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/{spring-boot/org.springframework.boot.test.autoconfigure.orm.jpa.AutoConfigureTestEntityManager => spring/org.springframework.boot.test.autoconfigure.orm.jpa.AutoConfigureTestEntityManager.imports} (100%) rename spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/{spring-boot/org.springframework.boot.test.autoconfigure.restdocs.AutoConfigureRestDocs => spring/org.springframework.boot.test.autoconfigure.restdocs.AutoConfigureRestDocs.imports} (100%) rename spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/{spring-boot/org.springframework.boot.test.autoconfigure.web.client.AutoConfigureMockRestServiceServer => spring/org.springframework.boot.test.autoconfigure.web.client.AutoConfigureMockRestServiceServer.imports} (100%) rename spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/{spring-boot/org.springframework.boot.test.autoconfigure.web.client.AutoConfigureWebClient => spring/org.springframework.boot.test.autoconfigure.web.client.AutoConfigureWebClient.imports} (100%) rename spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/{spring-boot/org.springframework.boot.test.autoconfigure.web.reactive.AutoConfigureWebFlux => spring/org.springframework.boot.test.autoconfigure.web.reactive.AutoConfigureWebFlux.imports} (100%) rename spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/{spring-boot/org.springframework.boot.test.autoconfigure.web.reactive.AutoConfigureWebTestClient => spring/org.springframework.boot.test.autoconfigure.web.reactive.AutoConfigureWebTestClient.imports} (100%) rename spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/{spring-boot/org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc => spring/org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc.imports} (100%) rename spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/{spring-boot/org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureWebMvc => spring/org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureWebMvc.imports} (100%) rename spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/{spring-boot/org.springframework.boot.test.autoconfigure.webservices.client.AutoConfigureMockWebServiceServer => spring/org.springframework.boot.test.autoconfigure.webservices.client.AutoConfigureMockWebServiceServer.imports} (100%) rename spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/{spring-boot/org.springframework.boot.test.autoconfigure.webservices.client.AutoConfigureWebServiceClient => spring/org.springframework.boot.test.autoconfigure.webservices.client.AutoConfigureWebServiceClient.imports} (100%) rename spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/{spring-boot/org.springframework.boot.test.autoconfigure.webservices.server.AutoConfigureMockWebServiceClient => spring/org.springframework.boot.test.autoconfigure.webservices.server.AutoConfigureMockWebServiceClient.imports} (100%) rename spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/{spring-boot/org.springframework.boot.test.autoconfigure.webservices.server.AutoConfigureWebServiceServer => spring/org.springframework.boot.test.autoconfigure.webservices.server.AutoConfigureWebServiceServer.imports} (100%) rename spring-boot-project/{spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/AutoConfigurationLoader.java => spring-boot/src/main/java/org/springframework/boot/context/annotation/ImportCandidates.java} (61%) rename spring-boot-project/{spring-boot-autoconfigure/src/test/resources/META-INF/spring-boot/org.springframework.boot.autoconfigure.AutoConfigurationLoaderTests$TestAutoConfiguration => spring-boot/src/main/resources/META-INF/spring/org.springframework.boot.context.annotation.ImportCandidatesTest$TestAnnotation.imports} (94%) rename spring-boot-project/{spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/AutoConfigurationLoaderTests.java => spring-boot/src/test/java/org/springframework/boot/context/annotation/ImportCandidatesTest.java} (67%) rename spring-boot-system-tests/spring-boot-deployment-tests/src/main/resources/META-INF/{spring-boot/org.springframework.boot.autoconfigure.AutoConfiguration => spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports} (100%) rename spring-boot-tests/spring-boot-integration-tests/spring-boot-server-tests/spring-boot-server-tests-app/src/main/resources/META-INF/{spring-boot/org.springframework.boot.autoconfigure.AutoConfiguration => spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports} (100%) diff --git a/buildSrc/src/main/java/org/springframework/boot/build/autoconfigure/AutoConfigurationMetadata.java b/buildSrc/src/main/java/org/springframework/boot/build/autoconfigure/AutoConfigurationMetadata.java index 535be934a7..13dcd108d3 100644 --- a/buildSrc/src/main/java/org/springframework/boot/build/autoconfigure/AutoConfigurationMetadata.java +++ b/buildSrc/src/main/java/org/springframework/boot/build/autoconfigure/AutoConfigurationMetadata.java @@ -66,7 +66,7 @@ public class AutoConfigurationMetadata extends DefaultTask { .withPathSensitivity(PathSensitivity.RELATIVE).withPropertyName("spring.factories"); getInputs() .file((Callable) () -> new File(this.sourceSet.getOutput().getResourcesDir(), - "META-INF/spring-boot/org.springframework.boot.autoconfigure.AutoConfiguration")) + "META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports")) .withPathSensitivity(PathSensitivity.RELATIVE) .withPropertyName("org.springframework.boot.autoconfigure.AutoConfiguration"); @@ -137,17 +137,17 @@ public class AutoConfigurationMetadata extends DefaultTask { /** * Reads auto-configurations from - * META-INF/spring-boot/org.springframework.boot.autoconfigure.AutoConfiguration. + * META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports. * @return auto-configurations */ private List readAutoConfigurationsFile() throws IOException { File file = new File(this.sourceSet.getOutput().getResourcesDir(), - "META-INF/spring-boot/org.springframework.boot.autoconfigure.AutoConfiguration"); + "META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports"); if (!file.exists()) { return Collections.emptyList(); } // Nearly identical copy of - // org.springframework.boot.autoconfigure.AutoConfigurationLoader.readAutoConfigurations + // org.springframework.boot.context.annotation.ImportCandidates.load try (BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(file)))) { List autoConfigurations = new ArrayList<>(); String line; diff --git a/buildSrc/src/main/java/org/springframework/boot/build/test/autoconfigure/TestSliceMetadata.java b/buildSrc/src/main/java/org/springframework/boot/build/test/autoconfigure/TestSliceMetadata.java index 958e052462..f135490547 100644 --- a/buildSrc/src/main/java/org/springframework/boot/build/test/autoconfigure/TestSliceMetadata.java +++ b/buildSrc/src/main/java/org/springframework/boot/build/test/autoconfigure/TestSliceMetadata.java @@ -106,7 +106,7 @@ public class TestSliceMetadata extends DefaultTask { Properties springFactories = readSpringFactories( new File(this.sourceSet.getOutput().getResourcesDir(), "META-INF/spring.factories")); readTestSlicesDirectory(springFactories, - new File(this.sourceSet.getOutput().getResourcesDir(), "META-INF/spring-boot/")); + new File(this.sourceSet.getOutput().getResourcesDir(), "META-INF/spring/")); for (File classesDir : this.sourceSet.getOutput().getClassesDirs()) { addTestSlices(testSlices, classesDir, metadataReaderFactory, springFactories); } @@ -123,14 +123,17 @@ public class TestSliceMetadata extends DefaultTask { * @param directory directory to scan */ private void readTestSlicesDirectory(Properties springFactories, File directory) { - File[] files = directory.listFiles(); + File[] files = directory.listFiles((dir, name) -> name.endsWith(".imports")); if (files == null) { return; } for (File file : files) { try { List lines = removeComments(Files.readAllLines(file.toPath())); - springFactories.setProperty(file.getName(), StringUtils.collectionToCommaDelimitedString(lines)); + String fileNameWithoutExtension = file.getName().substring(0, + file.getName().length() - ".imports".length()); + springFactories.setProperty(fileNameWithoutExtension, + StringUtils.collectionToCommaDelimitedString(lines)); } catch (IOException ex) { throw new UncheckedIOException("Failed to read file " + file, ex); diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/resources/META-INF/spring-boot/org.springframework.boot.autoconfigure.AutoConfiguration b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports similarity index 100% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/resources/META-INF/spring-boot/org.springframework.boot.autoconfigure.AutoConfiguration rename to spring-boot-project/spring-boot-actuator-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/AutoConfiguration.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/AutoConfiguration.java index 8ac17a19a0..3fee75c561 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/AutoConfiguration.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/AutoConfiguration.java @@ -24,6 +24,7 @@ import java.lang.annotation.Target; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.context.annotation.ImportCandidates; import org.springframework.context.annotation.Conditional; import org.springframework.context.annotation.Configuration; import org.springframework.core.io.support.SpringFactoriesLoader; @@ -34,9 +35,8 @@ import org.springframework.core.io.support.SpringFactoriesLoader; * {@link Configuration @Configuration} with the exception that * {@literal Configuration#proxyBeanMethods() proxyBeanMethods} is always {@code false}. *

- * They are located using the {@link AutoConfigurationLoader} and the - * {@link SpringFactoriesLoader} mechanism (keyed against - * {@link EnableAutoConfiguration}). + * They are located using {@link ImportCandidates} and the {@link SpringFactoriesLoader} + * mechanism (keyed against {@link EnableAutoConfiguration}). *

* Generally auto-configuration classes are marked as {@link Conditional @Conditional} * (most often using {@link ConditionalOnClass @ConditionalOnClass} and diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/AutoConfigurationExcludeFilter.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/AutoConfigurationExcludeFilter.java index 478653b0d6..53d8919970 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/AutoConfigurationExcludeFilter.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/AutoConfigurationExcludeFilter.java @@ -21,6 +21,7 @@ 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; @@ -63,11 +64,9 @@ public class AutoConfigurationExcludeFilter implements TypeFilter, BeanClassLoad protected List getAutoConfigurations() { if (this.autoConfigurations == null) { - List autoConfigurations = new ArrayList<>(); - autoConfigurations.addAll( + List autoConfigurations = new ArrayList<>( SpringFactoriesLoader.loadFactoryNames(EnableAutoConfiguration.class, this.beanClassLoader)); - autoConfigurations - .addAll(new AutoConfigurationLoader().loadNames(AutoConfiguration.class, this.beanClassLoader)); + ImportCandidates.load(AutoConfiguration.class, this.beanClassLoader).forEach(autoConfigurations::add); this.autoConfigurations = autoConfigurations; } return this.autoConfigurations; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/AutoConfigurationImportSelector.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/AutoConfigurationImportSelector.java index 8490bcef77..41569923e9 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/AutoConfigurationImportSelector.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/AutoConfigurationImportSelector.java @@ -40,6 +40,7 @@ import org.springframework.beans.factory.BeanFactory; import org.springframework.beans.factory.BeanFactoryAware; import org.springframework.beans.factory.NoSuchBeanDefinitionException; import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; +import org.springframework.boot.context.annotation.ImportCandidates; import org.springframework.boot.context.properties.bind.Binder; import org.springframework.context.EnvironmentAware; import org.springframework.context.ResourceLoaderAware; @@ -168,7 +169,7 @@ public class AutoConfigurationImportSelector implements DeferredImportSelector, /** * Return the auto-configuration class names that should be considered. By default - * this method will load candidates using {@link AutoConfigurationLoader} with + * this method will load candidates using {@link ImportCandidates} with * {@link #getSpringFactoriesLoaderFactoryClass()}. For backward compatible reasons it * will also consider {@link SpringFactoriesLoader} with * {@link #getSpringFactoriesLoaderFactoryClass()}. @@ -178,12 +179,11 @@ public class AutoConfigurationImportSelector implements DeferredImportSelector, * @return a list of candidate configurations */ protected List getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) { - List configurations = new ArrayList<>(); - configurations.addAll( + List configurations = new ArrayList<>( SpringFactoriesLoader.loadFactoryNames(getSpringFactoriesLoaderFactoryClass(), getBeanClassLoader())); - configurations.addAll(new AutoConfigurationLoader().loadNames(AutoConfiguration.class, getBeanClassLoader())); + ImportCandidates.load(AutoConfiguration.class, getBeanClassLoader()).forEach(configurations::add); Assert.notEmpty(configurations, - "No auto configuration classes found in META-INF/spring.factories nor in META-INF/spring-boot/org.springframework.boot.autoconfigure.AutoConfiguration. If you " + "No auto configuration classes found in META-INF/spring.factories nor 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; } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/EnableAutoConfiguration.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/EnableAutoConfiguration.java index 624d9f3e9e..4030ef5e8c 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/EnableAutoConfiguration.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/EnableAutoConfiguration.java @@ -26,6 +26,7 @@ import java.lang.annotation.Target; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.context.annotation.ImportCandidates; import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory; import org.springframework.boot.web.servlet.server.ServletWebServerFactory; import org.springframework.context.annotation.Conditional; @@ -60,7 +61,7 @@ import org.springframework.core.io.support.SpringFactoriesLoader; * and classes can be searched. *

* Auto-configuration classes are regular Spring {@link Configuration @Configuration} - * beans. They are located using the {@link AutoConfigurationLoader} and the + * 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 * {@link ConditionalOnClass @ConditionalOnClass} and diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/ImportAutoConfiguration.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/ImportAutoConfiguration.java index 5bfb1f2353..9e557d6f03 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/ImportAutoConfiguration.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/ImportAutoConfiguration.java @@ -59,8 +59,8 @@ public @interface ImportAutoConfiguration { /** * The auto-configuration classes that should be imported. When empty, the classes are - * specified using a file in {@code META-INF/spring-boot} where the file name is the - * fully-qualified name of the annotated class. + * specified using a file in {@code META-INF/spring} where the file name is the + * fully-qualified name of the annotated class, suffixed with '.imports'. * @return the classes to import */ @AliasFor("value") diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/ImportAutoConfigurationImportSelector.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/ImportAutoConfigurationImportSelector.java index 0b2c500885..f234a7ad35 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/ImportAutoConfigurationImportSelector.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/ImportAutoConfigurationImportSelector.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2021 the original author or authors. + * Copyright 2012-2022 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. @@ -28,6 +28,7 @@ import java.util.Map; import java.util.Set; import org.springframework.boot.context.annotation.DeterminableImports; +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; @@ -95,9 +96,9 @@ class ImportAutoConfigurationImportSelector extends AutoConfigurationImportSelec } protected Collection loadFactoryNames(Class source) { - List factoryNames = new ArrayList<>(); - factoryNames.addAll(SpringFactoriesLoader.loadFactoryNames(source, getBeanClassLoader())); - factoryNames.addAll(new AutoConfigurationLoader().loadNames(source, getBeanClassLoader())); + List factoryNames = new ArrayList<>( + SpringFactoriesLoader.loadFactoryNames(source, getBeanClassLoader())); + ImportCandidates.load(source, getBeanClassLoader()).forEach(factoryNames::add); return factoryNames; } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/resources/META-INF/spring-boot/org.springframework.boot.autoconfigure.AutoConfiguration b/spring-boot-project/spring-boot-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports similarity index 100% rename from spring-boot-project/spring-boot-autoconfigure/src/main/resources/META-INF/spring-boot/org.springframework.boot.autoconfigure.AutoConfiguration rename to spring-boot-project/spring-boot-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/AutoConfigurationImportSelectorTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/AutoConfigurationImportSelectorTests.java index a98311565d..e22f3840ee 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/AutoConfigurationImportSelectorTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/AutoConfigurationImportSelectorTests.java @@ -32,6 +32,7 @@ import org.springframework.beans.factory.support.DefaultListableBeanFactory; import org.springframework.boot.autoconfigure.freemarker.FreeMarkerAutoConfiguration; import org.springframework.boot.autoconfigure.mustache.MustacheAutoConfiguration; import org.springframework.boot.autoconfigure.thymeleaf.ThymeleafAutoConfiguration; +import org.springframework.boot.context.annotation.ImportCandidates; import org.springframework.context.annotation.Configuration; import org.springframework.core.io.DefaultResourceLoader; import org.springframework.core.type.AnnotationMetadata; @@ -212,7 +213,10 @@ class AutoConfigurationImportSelectorTests { } private List getAutoConfigurationClassNames() { - return new AutoConfigurationLoader().loadNames(AutoConfiguration.class, getClass().getClassLoader()); + List autoConfigurationClassNames = new ArrayList<>(); + ImportCandidates.load(AutoConfiguration.class, getClass().getClassLoader()) + .forEach(autoConfigurationClassNames::add); + return autoConfigurationClassNames; } private class TestAutoConfigurationImportSelector extends AutoConfigurationImportSelector { diff --git a/spring-boot-project/spring-boot-devtools/src/main/resources/META-INF/spring-boot/org.springframework.boot.autoconfigure.AutoConfiguration b/spring-boot-project/spring-boot-devtools/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports similarity index 100% rename from spring-boot-project/spring-boot-devtools/src/main/resources/META-INF/spring-boot/org.springframework.boot.autoconfigure.AutoConfiguration rename to spring-boot-project/spring-boot-devtools/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports diff --git a/spring-boot-project/spring-boot-docs/src/docs/asciidoc/features/developing-auto-configuration.adoc b/spring-boot-project/spring-boot-docs/src/docs/asciidoc/features/developing-auto-configuration.adoc index 1c72edbb68..5b2220638a 100644 --- a/spring-boot-project/spring-boot-docs/src/docs/asciidoc/features/developing-auto-configuration.adoc +++ b/spring-boot-project/spring-boot-docs/src/docs/asciidoc/features/developing-auto-configuration.adoc @@ -18,14 +18,14 @@ Additional `@Conditional` annotations are used to constrain when the auto-config Usually, auto-configuration classes use `@ConditionalOnClass` and `@ConditionalOnMissingBean` annotations. This ensures that auto-configuration applies only when relevant classes are found and when you have not declared your own `@Configuration`. -You can browse the source code of {spring-boot-autoconfigure-module-code}[`spring-boot-autoconfigure`] to see the `@Configuration` classes that Spring provides (see the {spring-boot-code}/spring-boot-project/spring-boot-autoconfigure/src/main/resources/META-INF/spring-boot/org.springframework.boot.autoconfigure.AutoConfiguration[`META-INF/spring-boot/org.springframework.boot.autoconfigure.AutoConfiguration`] file). +You can browse the source code of {spring-boot-autoconfigure-module-code}[`spring-boot-autoconfigure`] to see the `@Configuration` classes that Spring provides (see the {spring-boot-code}/spring-boot-project/spring-boot-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports[`META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports`] file). [[features.developing-auto-configuration.locating-auto-configuration-candidates]] === Locating Auto-configuration Candidates -Spring Boot checks for the presence of a `META-INF/spring-boot/org.springframework.boot.autoconfigure.AutoConfiguration` file within your published jar. +Spring Boot checks for the presence of a `META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports` file within your published jar. The file should list your configuration classes, as shown in the following example: [indent=0] diff --git a/spring-boot-project/spring-boot-docs/src/docs/asciidoc/features/testing.adoc b/spring-boot-project/spring-boot-docs/src/docs/asciidoc/features/testing.adoc index a80a50a027..f809bf5170 100644 --- a/spring-boot-project/spring-boot-docs/src/docs/asciidoc/features/testing.adoc +++ b/spring-boot-project/spring-boot-docs/src/docs/asciidoc/features/testing.adoc @@ -769,9 +769,9 @@ include::code:MyJdbcTests[] NOTE: Make sure to not use the regular `@Import` annotation to import auto-configurations as they are handled in a specific way by Spring Boot. -Alternatively, additional auto-configurations can be added for any use of a slice annotation by registering them in a file stored in `META-INF/spring-boot` as shown in the following example: +Alternatively, additional auto-configurations can be added for any use of a slice annotation by registering them in a file stored in `META-INF/spring` as shown in the following example: -.META-INF/spring-boot/org.springframework.boot.test.autoconfigure.jdbc.JdbcTest +.META-INF/spring/org.springframework.boot.test.autoconfigure.jdbc.JdbcTest.imports [indent=0] ---- com.example.IntegrationAutoConfiguration diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring-boot/org.springframework.boot.test.autoconfigure.core.AutoConfigureCache b/spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.test.autoconfigure.core.AutoConfigureCache.imports similarity index 100% rename from spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring-boot/org.springframework.boot.test.autoconfigure.core.AutoConfigureCache rename to spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.test.autoconfigure.core.AutoConfigureCache.imports diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring-boot/org.springframework.boot.test.autoconfigure.data.cassandra.AutoConfigureDataCassandra b/spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.test.autoconfigure.data.cassandra.AutoConfigureDataCassandra.imports similarity index 100% rename from spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring-boot/org.springframework.boot.test.autoconfigure.data.cassandra.AutoConfigureDataCassandra rename to spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.test.autoconfigure.data.cassandra.AutoConfigureDataCassandra.imports diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring-boot/org.springframework.boot.test.autoconfigure.data.jdbc.AutoConfigureDataJdbc b/spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.test.autoconfigure.data.jdbc.AutoConfigureDataJdbc.imports similarity index 100% rename from spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring-boot/org.springframework.boot.test.autoconfigure.data.jdbc.AutoConfigureDataJdbc rename to spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.test.autoconfigure.data.jdbc.AutoConfigureDataJdbc.imports diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring-boot/org.springframework.boot.test.autoconfigure.data.ldap.AutoConfigureDataLdap b/spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.test.autoconfigure.data.ldap.AutoConfigureDataLdap.imports similarity index 100% rename from spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring-boot/org.springframework.boot.test.autoconfigure.data.ldap.AutoConfigureDataLdap rename to spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.test.autoconfigure.data.ldap.AutoConfigureDataLdap.imports diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring-boot/org.springframework.boot.test.autoconfigure.data.mongo.AutoConfigureDataMongo b/spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.test.autoconfigure.data.mongo.AutoConfigureDataMongo.imports similarity index 100% rename from spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring-boot/org.springframework.boot.test.autoconfigure.data.mongo.AutoConfigureDataMongo rename to spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.test.autoconfigure.data.mongo.AutoConfigureDataMongo.imports diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring-boot/org.springframework.boot.test.autoconfigure.data.neo4j.AutoConfigureDataNeo4j b/spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.test.autoconfigure.data.neo4j.AutoConfigureDataNeo4j.imports similarity index 100% rename from spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring-boot/org.springframework.boot.test.autoconfigure.data.neo4j.AutoConfigureDataNeo4j rename to spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.test.autoconfigure.data.neo4j.AutoConfigureDataNeo4j.imports diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring-boot/org.springframework.boot.test.autoconfigure.data.r2dbc.AutoConfigureDataR2dbc b/spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.test.autoconfigure.data.r2dbc.AutoConfigureDataR2dbc.imports similarity index 100% rename from spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring-boot/org.springframework.boot.test.autoconfigure.data.r2dbc.AutoConfigureDataR2dbc rename to spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.test.autoconfigure.data.r2dbc.AutoConfigureDataR2dbc.imports diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring-boot/org.springframework.boot.test.autoconfigure.data.redis.AutoConfigureDataRedis b/spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.test.autoconfigure.data.redis.AutoConfigureDataRedis.imports similarity index 100% rename from spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring-boot/org.springframework.boot.test.autoconfigure.data.redis.AutoConfigureDataRedis rename to spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.test.autoconfigure.data.redis.AutoConfigureDataRedis.imports diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring-boot/org.springframework.boot.test.autoconfigure.graphql.AutoConfigureGraphQl b/spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.test.autoconfigure.graphql.AutoConfigureGraphQl.imports similarity index 100% rename from spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring-boot/org.springframework.boot.test.autoconfigure.graphql.AutoConfigureGraphQl rename to spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.test.autoconfigure.graphql.AutoConfigureGraphQl.imports diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring-boot/org.springframework.boot.test.autoconfigure.graphql.tester.AutoConfigureGraphQlTester b/spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.test.autoconfigure.graphql.tester.AutoConfigureGraphQlTester.imports similarity index 100% rename from spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring-boot/org.springframework.boot.test.autoconfigure.graphql.tester.AutoConfigureGraphQlTester rename to spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.test.autoconfigure.graphql.tester.AutoConfigureGraphQlTester.imports diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring-boot/org.springframework.boot.test.autoconfigure.graphql.tester.AutoConfigureWebGraphQlTester b/spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.test.autoconfigure.graphql.tester.AutoConfigureWebGraphQlTester.imports similarity index 100% rename from spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring-boot/org.springframework.boot.test.autoconfigure.graphql.tester.AutoConfigureWebGraphQlTester rename to spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.test.autoconfigure.graphql.tester.AutoConfigureWebGraphQlTester.imports diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring-boot/org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureJdbc b/spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureJdbc.imports similarity index 100% rename from spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring-boot/org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureJdbc rename to spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureJdbc.imports diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring-boot/org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase b/spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase.imports similarity index 100% rename from spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring-boot/org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase rename to spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase.imports diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring-boot/org.springframework.boot.test.autoconfigure.jooq.AutoConfigureJooq b/spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.test.autoconfigure.jooq.AutoConfigureJooq.imports similarity index 100% rename from spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring-boot/org.springframework.boot.test.autoconfigure.jooq.AutoConfigureJooq rename to spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.test.autoconfigure.jooq.AutoConfigureJooq.imports diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring-boot/org.springframework.boot.test.autoconfigure.json.AutoConfigureJson b/spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.test.autoconfigure.json.AutoConfigureJson.imports similarity index 100% rename from spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring-boot/org.springframework.boot.test.autoconfigure.json.AutoConfigureJson rename to spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.test.autoconfigure.json.AutoConfigureJson.imports diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring-boot/org.springframework.boot.test.autoconfigure.json.AutoConfigureJsonTesters b/spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.test.autoconfigure.json.AutoConfigureJsonTesters.imports similarity index 100% rename from spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring-boot/org.springframework.boot.test.autoconfigure.json.AutoConfigureJsonTesters rename to spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.test.autoconfigure.json.AutoConfigureJsonTesters.imports diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring-boot/org.springframework.boot.test.autoconfigure.orm.jpa.AutoConfigureDataJpa b/spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.test.autoconfigure.orm.jpa.AutoConfigureDataJpa.imports similarity index 100% rename from spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring-boot/org.springframework.boot.test.autoconfigure.orm.jpa.AutoConfigureDataJpa rename to spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.test.autoconfigure.orm.jpa.AutoConfigureDataJpa.imports diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring-boot/org.springframework.boot.test.autoconfigure.orm.jpa.AutoConfigureTestEntityManager b/spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.test.autoconfigure.orm.jpa.AutoConfigureTestEntityManager.imports similarity index 100% rename from spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring-boot/org.springframework.boot.test.autoconfigure.orm.jpa.AutoConfigureTestEntityManager rename to spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.test.autoconfigure.orm.jpa.AutoConfigureTestEntityManager.imports diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring-boot/org.springframework.boot.test.autoconfigure.restdocs.AutoConfigureRestDocs b/spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.test.autoconfigure.restdocs.AutoConfigureRestDocs.imports similarity index 100% rename from spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring-boot/org.springframework.boot.test.autoconfigure.restdocs.AutoConfigureRestDocs rename to spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.test.autoconfigure.restdocs.AutoConfigureRestDocs.imports diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring-boot/org.springframework.boot.test.autoconfigure.web.client.AutoConfigureMockRestServiceServer b/spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.test.autoconfigure.web.client.AutoConfigureMockRestServiceServer.imports similarity index 100% rename from spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring-boot/org.springframework.boot.test.autoconfigure.web.client.AutoConfigureMockRestServiceServer rename to spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.test.autoconfigure.web.client.AutoConfigureMockRestServiceServer.imports diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring-boot/org.springframework.boot.test.autoconfigure.web.client.AutoConfigureWebClient b/spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.test.autoconfigure.web.client.AutoConfigureWebClient.imports similarity index 100% rename from spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring-boot/org.springframework.boot.test.autoconfigure.web.client.AutoConfigureWebClient rename to spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.test.autoconfigure.web.client.AutoConfigureWebClient.imports diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring-boot/org.springframework.boot.test.autoconfigure.web.reactive.AutoConfigureWebFlux b/spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.test.autoconfigure.web.reactive.AutoConfigureWebFlux.imports similarity index 100% rename from spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring-boot/org.springframework.boot.test.autoconfigure.web.reactive.AutoConfigureWebFlux rename to spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.test.autoconfigure.web.reactive.AutoConfigureWebFlux.imports diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring-boot/org.springframework.boot.test.autoconfigure.web.reactive.AutoConfigureWebTestClient b/spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.test.autoconfigure.web.reactive.AutoConfigureWebTestClient.imports similarity index 100% rename from spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring-boot/org.springframework.boot.test.autoconfigure.web.reactive.AutoConfigureWebTestClient rename to spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.test.autoconfigure.web.reactive.AutoConfigureWebTestClient.imports diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring-boot/org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc b/spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc.imports similarity index 100% rename from spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring-boot/org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc rename to spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc.imports diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring-boot/org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureWebMvc b/spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureWebMvc.imports similarity index 100% rename from spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring-boot/org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureWebMvc rename to spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureWebMvc.imports diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring-boot/org.springframework.boot.test.autoconfigure.webservices.client.AutoConfigureMockWebServiceServer b/spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.test.autoconfigure.webservices.client.AutoConfigureMockWebServiceServer.imports similarity index 100% rename from spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring-boot/org.springframework.boot.test.autoconfigure.webservices.client.AutoConfigureMockWebServiceServer rename to spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.test.autoconfigure.webservices.client.AutoConfigureMockWebServiceServer.imports diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring-boot/org.springframework.boot.test.autoconfigure.webservices.client.AutoConfigureWebServiceClient b/spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.test.autoconfigure.webservices.client.AutoConfigureWebServiceClient.imports similarity index 100% rename from spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring-boot/org.springframework.boot.test.autoconfigure.webservices.client.AutoConfigureWebServiceClient rename to spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.test.autoconfigure.webservices.client.AutoConfigureWebServiceClient.imports diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring-boot/org.springframework.boot.test.autoconfigure.webservices.server.AutoConfigureMockWebServiceClient b/spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.test.autoconfigure.webservices.server.AutoConfigureMockWebServiceClient.imports similarity index 100% rename from spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring-boot/org.springframework.boot.test.autoconfigure.webservices.server.AutoConfigureMockWebServiceClient rename to spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.test.autoconfigure.webservices.server.AutoConfigureMockWebServiceClient.imports diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring-boot/org.springframework.boot.test.autoconfigure.webservices.server.AutoConfigureWebServiceServer b/spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.test.autoconfigure.webservices.server.AutoConfigureWebServiceServer.imports similarity index 100% rename from spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring-boot/org.springframework.boot.test.autoconfigure.webservices.server.AutoConfigureWebServiceServer rename to spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.test.autoconfigure.webservices.server.AutoConfigureWebServiceServer.imports diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/AutoConfigurationLoader.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/context/annotation/ImportCandidates.java similarity index 61% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/AutoConfigurationLoader.java rename to spring-boot-project/spring-boot/src/main/java/org/springframework/boot/context/annotation/ImportCandidates.java index 5f8dc2b829..817cf40f53 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/AutoConfigurationLoader.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/context/annotation/ImportCandidates.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure; +package org.springframework.boot.context.annotation; import java.io.BufferedReader; import java.io.IOException; @@ -22,57 +22,76 @@ import java.io.InputStreamReader; import java.net.URL; import java.nio.charset.StandardCharsets; import java.util.ArrayList; +import java.util.Collections; import java.util.Enumeration; +import java.util.Iterator; import java.util.List; +import org.jetbrains.annotations.NotNull; + import org.springframework.core.io.UrlResource; -import org.springframework.core.io.support.SpringFactoriesLoader; import org.springframework.util.Assert; /** - * Loads the names of annotated classes, usually @{@link AutoConfiguration}. + * Contains import candidates, usually auto-configurations. * - * The names of the classes are stored in files named META-INF/spring-boot/{full qualified - * name of the annotation}. Every line contains the full qualified class name of the - * annotated class. Comments are supported using the # character. + * The {@link #load(Class, ClassLoader)} method can be used to discover the import + * candidates. * * @author Moritz Halbritter - * @see AutoConfiguration - * @see SpringFactoriesLoader + * @since 2.7.0 */ -class AutoConfigurationLoader { +public final class ImportCandidates implements Iterable { - private static final String LOCATION = "META-INF/spring-boot/"; + private static final String LOCATION = "META-INF/spring/%s.imports"; private static final String COMMENT_START = "#"; + private final List candidates; + + private ImportCandidates(List candidates) { + Assert.notNull(candidates, "'candidates' must not be null"); + this.candidates = Collections.unmodifiableList(candidates); + } + + @NotNull + @Override + public Iterator iterator() { + return this.candidates.iterator(); + } + /** - * Loads the names of annotated classes. + * Loads the names of import candidates from the classpath. + * + * The names of the import candidates are stored in files named + * {@code META-INF/spring/full-qualified-annotation-name.import} on the classpath. + * Every line contains the full qualified name of the candidate class. Comments are + * supported using the # character. * @param annotation annotation to load * @param classLoader class loader to use for loading * @return list of names of annotated classes */ - List loadNames(Class annotation, ClassLoader classLoader) { + public static ImportCandidates load(Class annotation, ClassLoader classLoader) { Assert.notNull(annotation, "'annotation' must not be null"); ClassLoader classLoaderToUse = decideClassloader(classLoader); - String location = LOCATION + annotation.getName(); + String location = String.format(LOCATION, annotation.getName()); Enumeration urls = findUrlsInClasspath(classLoaderToUse, location); List autoConfigurations = new ArrayList<>(); while (urls.hasMoreElements()) { URL url = urls.nextElement(); autoConfigurations.addAll(readAutoConfigurations(url)); } - return autoConfigurations; + return new ImportCandidates(autoConfigurations); } - private ClassLoader decideClassloader(ClassLoader classLoader) { + private static ClassLoader decideClassloader(ClassLoader classLoader) { if (classLoader == null) { - return AutoConfigurationLoader.class.getClassLoader(); + return ImportCandidates.class.getClassLoader(); } return classLoader; } - private Enumeration findUrlsInClasspath(ClassLoader classLoader, String location) { + private static Enumeration findUrlsInClasspath(ClassLoader classLoader, String location) { try { return classLoader.getResources(location); } @@ -82,7 +101,7 @@ class AutoConfigurationLoader { } } - private List readAutoConfigurations(URL url) { + private static List readAutoConfigurations(URL url) { try (BufferedReader reader = new BufferedReader( new InputStreamReader(new UrlResource(url).getInputStream(), StandardCharsets.UTF_8))) { List autoConfigurations = new ArrayList<>(); @@ -102,7 +121,7 @@ class AutoConfigurationLoader { } } - private String stripComment(String line) { + private static String stripComment(String line) { int commentStart = line.indexOf(COMMENT_START); if (commentStart == -1) { return line; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/resources/META-INF/spring-boot/org.springframework.boot.autoconfigure.AutoConfigurationLoaderTests$TestAutoConfiguration b/spring-boot-project/spring-boot/src/main/resources/META-INF/spring/org.springframework.boot.context.annotation.ImportCandidatesTest$TestAnnotation.imports similarity index 94% rename from spring-boot-project/spring-boot-autoconfigure/src/test/resources/META-INF/spring-boot/org.springframework.boot.autoconfigure.AutoConfigurationLoaderTests$TestAutoConfiguration rename to spring-boot-project/spring-boot/src/main/resources/META-INF/spring/org.springframework.boot.context.annotation.ImportCandidatesTest$TestAnnotation.imports index d42712a8c2..8274f7c72c 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/resources/META-INF/spring-boot/org.springframework.boot.autoconfigure.AutoConfigurationLoaderTests$TestAutoConfiguration +++ b/spring-boot-project/spring-boot/src/main/resources/META-INF/spring/org.springframework.boot.context.annotation.ImportCandidatesTest$TestAnnotation.imports @@ -3,4 +3,4 @@ class1 class2 # with comment at the end # Comment with some whitespace in front -class3 \ No newline at end of file +class3 diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/AutoConfigurationLoaderTests.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/context/annotation/ImportCandidatesTest.java similarity index 67% rename from spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/AutoConfigurationLoaderTests.java rename to spring-boot-project/spring-boot/src/test/java/org/springframework/boot/context/annotation/ImportCandidatesTest.java index ef63167386..914e2d6198 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/AutoConfigurationLoaderTests.java +++ b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/context/annotation/ImportCandidatesTest.java @@ -14,39 +14,28 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure; +package org.springframework.boot.context.annotation; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; -import java.util.List; -import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.assertThat; -class AutoConfigurationLoaderTests { - - private AutoConfigurationLoader sut; - - @BeforeEach - void setUp() { - this.sut = new AutoConfigurationLoader(); - } +class ImportCandidatesTest { @Test - void loadNames() { - List classNames = this.sut.loadNames(TestAutoConfiguration.class, null); - - assertThat(classNames).containsExactly("class1", "class2", "class3"); + void loadReadsFromClasspathFile() { + ImportCandidates candidates = ImportCandidates.load(TestAnnotation.class, null); + assertThat(candidates).containsExactly("class1", "class2", "class3"); } - @AutoConfiguration @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) - public @interface TestAutoConfiguration { + public @interface TestAnnotation { } diff --git a/spring-boot-system-tests/spring-boot-deployment-tests/src/main/resources/META-INF/spring-boot/org.springframework.boot.autoconfigure.AutoConfiguration b/spring-boot-system-tests/spring-boot-deployment-tests/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports similarity index 100% rename from spring-boot-system-tests/spring-boot-deployment-tests/src/main/resources/META-INF/spring-boot/org.springframework.boot.autoconfigure.AutoConfiguration rename to spring-boot-system-tests/spring-boot-deployment-tests/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports diff --git a/spring-boot-tests/spring-boot-integration-tests/spring-boot-server-tests/spring-boot-server-tests-app/src/main/resources/META-INF/spring-boot/org.springframework.boot.autoconfigure.AutoConfiguration b/spring-boot-tests/spring-boot-integration-tests/spring-boot-server-tests/spring-boot-server-tests-app/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports similarity index 100% rename from spring-boot-tests/spring-boot-integration-tests/spring-boot-server-tests/spring-boot-server-tests-app/src/main/resources/META-INF/spring-boot/org.springframework.boot.autoconfigure.AutoConfiguration rename to spring-boot-tests/spring-boot-integration-tests/spring-boot-server-tests/spring-boot-server-tests-app/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports