Generate the AutoConfiguration.imports file from annotations

This commit adds the `AutoConfigurationImportsAnnotationProcessor` to
the `spring-boot-autoconfigure-processor` annotation processor
module. When added to a project build, the annotation processor will
generate the
`org.springframework.boot.autoconfigure.AutoConfiguration.imports`
file automatically from `@AutoConfiguration`-annotated classes. It
also applies the annotation processor to the Spring Boot build.

Closes gh-31228
This commit is contained in:
Scott Frederick 2022-09-02 13:24:26 -05:00
parent 795ea289db
commit da4de7d67d
16 changed files with 265 additions and 338 deletions

View File

@ -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,16 +41,18 @@ 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 {
private static final String IMPORTS_FILE_PATH = "META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports";
private static final String COMMENT_START = "#";
private SourceSet sourceSet;
@ -60,13 +60,7 @@ 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"))
getInputs().file((Callable<File>) this::findAutoConfigurationImportsFile)
.withPathSensitivity(PathSensitivity.RELATIVE)
.withPropertyName("org.springframework.boot.autoconfigure.AutoConfiguration");
@ -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,61 +112,41 @@ 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.
* @return auto-configurations
*/
private List<String> readAutoConfigurationsFile() throws IOException {
File file = new File(this.sourceSet.getOutput().getResourcesDir(),
"META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports");
if (!file.exists()) {
File file = findAutoConfigurationImportsFile();
if (file == null) {
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 findAutoConfigurationImportsFile() {
return findFileInClassesDirs(IMPORTS_FILE_PATH);
}
private File findClassFile(String className) {
String classFileName = className.replace(".", "/") + ".class";
return findFileInClassesDirs(className.replace(".", "/") + ".class");
}
private File findFileInClassesDirs(String fileName) {
for (File classesDir : this.sourceSet.getOutput().getClassesDirs()) {
File classFile = new File(classesDir, classFileName);
File classFile = new File(classesDir, fileName);
if (classFile.isFile()) {
return classFile;
}
@ -182,12 +154,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;
}
}

View File

@ -18,7 +18,6 @@ package org.springframework.boot.build.autoconfigure;
import java.io.File;
import java.util.Collections;
import java.util.concurrent.Callable;
import org.gradle.api.Plugin;
import org.gradle.api.Project;
@ -43,6 +42,7 @@ import org.springframework.boot.build.context.properties.ConfigurationProperties
* </ul>
*
* @author Andy Wilkinson
* @author Scott Frederick
*/
public class AutoConfigurationPlugin implements Plugin<Project> {
@ -62,9 +62,6 @@ public class AutoConfigurationPlugin implements Plugin<Project> {
annotationProcessors.getDependencies()
.add(project.getDependencies().project(Collections.singletonMap("path",
":spring-boot-project:spring-boot-tools:spring-boot-autoconfigure-processor")));
annotationProcessors.getDependencies()
.add(project.getDependencies().project(Collections.singletonMap("path",
":spring-boot-project:spring-boot-tools:spring-boot-configuration-processor")));
project.getTasks().create("autoConfigurationMetadata", AutoConfigurationMetadata.class, (task) -> {
SourceSet main = project.getExtensions().getByType(JavaPluginExtension.class).getSourceSets()
.getByName(SourceSet.MAIN_SOURCE_SET_NAME);
@ -72,7 +69,7 @@ public class AutoConfigurationPlugin implements Plugin<Project> {
task.dependsOn(main.getClassesTaskName());
task.setOutputFile(new File(project.getBuildDir(), "auto-configuration-metadata.properties"));
project.getArtifacts().add(AutoConfigurationPlugin.AUTO_CONFIGURATION_METADATA_CONFIGURATION_NAME,
project.provider((Callable<File>) task::getOutputFile), (artifact) -> artifact.builtBy(task));
project.provider(task::getOutputFile), (artifact) -> artifact.builtBy(task));
});
});
}

View File

@ -1,109 +0,0 @@
org.springframework.boot.actuate.autoconfigure.amqp.RabbitHealthContributorAutoConfiguration
org.springframework.boot.actuate.autoconfigure.audit.AuditAutoConfiguration
org.springframework.boot.actuate.autoconfigure.audit.AuditEventsEndpointAutoConfiguration
org.springframework.boot.actuate.autoconfigure.availability.AvailabilityHealthContributorAutoConfiguration
org.springframework.boot.actuate.autoconfigure.availability.AvailabilityProbesAutoConfiguration
org.springframework.boot.actuate.autoconfigure.beans.BeansEndpointAutoConfiguration
org.springframework.boot.actuate.autoconfigure.cache.CachesEndpointAutoConfiguration
org.springframework.boot.actuate.autoconfigure.cassandra.CassandraHealthContributorAutoConfiguration
org.springframework.boot.actuate.autoconfigure.cassandra.CassandraReactiveHealthContributorAutoConfiguration
org.springframework.boot.actuate.autoconfigure.cloudfoundry.servlet.CloudFoundryActuatorAutoConfiguration
org.springframework.boot.actuate.autoconfigure.cloudfoundry.reactive.ReactiveCloudFoundryActuatorAutoConfiguration
org.springframework.boot.actuate.autoconfigure.condition.ConditionsReportEndpointAutoConfiguration
org.springframework.boot.actuate.autoconfigure.context.properties.ConfigurationPropertiesReportEndpointAutoConfiguration
org.springframework.boot.actuate.autoconfigure.context.ShutdownEndpointAutoConfiguration
org.springframework.boot.actuate.autoconfigure.couchbase.CouchbaseHealthContributorAutoConfiguration
org.springframework.boot.actuate.autoconfigure.couchbase.CouchbaseReactiveHealthContributorAutoConfiguration
org.springframework.boot.actuate.autoconfigure.data.elasticsearch.ElasticsearchReactiveHealthContributorAutoConfiguration
org.springframework.boot.actuate.autoconfigure.elasticsearch.ElasticsearchRestHealthContributorAutoConfiguration
org.springframework.boot.actuate.autoconfigure.endpoint.EndpointAutoConfiguration
org.springframework.boot.actuate.autoconfigure.endpoint.jmx.JmxEndpointAutoConfiguration
org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointAutoConfiguration
org.springframework.boot.actuate.autoconfigure.env.EnvironmentEndpointAutoConfiguration
org.springframework.boot.actuate.autoconfigure.flyway.FlywayEndpointAutoConfiguration
org.springframework.boot.actuate.autoconfigure.hazelcast.HazelcastHealthContributorAutoConfiguration
org.springframework.boot.actuate.autoconfigure.health.HealthContributorAutoConfiguration
org.springframework.boot.actuate.autoconfigure.health.HealthEndpointAutoConfiguration
org.springframework.boot.actuate.autoconfigure.influx.InfluxDbHealthContributorAutoConfiguration
org.springframework.boot.actuate.autoconfigure.info.InfoContributorAutoConfiguration
org.springframework.boot.actuate.autoconfigure.info.InfoEndpointAutoConfiguration
org.springframework.boot.actuate.autoconfigure.integration.IntegrationGraphEndpointAutoConfiguration
org.springframework.boot.actuate.autoconfigure.jdbc.DataSourceHealthContributorAutoConfiguration
org.springframework.boot.actuate.autoconfigure.jms.JmsHealthContributorAutoConfiguration
org.springframework.boot.actuate.autoconfigure.ldap.LdapHealthContributorAutoConfiguration
org.springframework.boot.actuate.autoconfigure.liquibase.LiquibaseEndpointAutoConfiguration
org.springframework.boot.actuate.autoconfigure.logging.LogFileWebEndpointAutoConfiguration
org.springframework.boot.actuate.autoconfigure.logging.LoggersEndpointAutoConfiguration
org.springframework.boot.actuate.autoconfigure.mail.MailHealthContributorAutoConfiguration
org.springframework.boot.actuate.autoconfigure.management.HeapDumpWebEndpointAutoConfiguration
org.springframework.boot.actuate.autoconfigure.management.ThreadDumpEndpointAutoConfiguration
org.springframework.boot.actuate.autoconfigure.metrics.CompositeMeterRegistryAutoConfiguration
org.springframework.boot.actuate.autoconfigure.metrics.JvmMetricsAutoConfiguration
org.springframework.boot.actuate.autoconfigure.metrics.KafkaMetricsAutoConfiguration
org.springframework.boot.actuate.autoconfigure.metrics.Log4J2MetricsAutoConfiguration
org.springframework.boot.actuate.autoconfigure.metrics.LogbackMetricsAutoConfiguration
org.springframework.boot.actuate.autoconfigure.metrics.MetricsAutoConfiguration
org.springframework.boot.actuate.autoconfigure.metrics.MetricsEndpointAutoConfiguration
org.springframework.boot.actuate.autoconfigure.metrics.SystemMetricsAutoConfiguration
org.springframework.boot.actuate.autoconfigure.metrics.amqp.RabbitMetricsAutoConfiguration
org.springframework.boot.actuate.autoconfigure.metrics.cache.CacheMetricsAutoConfiguration
org.springframework.boot.actuate.autoconfigure.metrics.data.RepositoryMetricsAutoConfiguration
org.springframework.boot.actuate.autoconfigure.metrics.export.appoptics.AppOpticsMetricsExportAutoConfiguration
org.springframework.boot.actuate.autoconfigure.metrics.export.atlas.AtlasMetricsExportAutoConfiguration
org.springframework.boot.actuate.autoconfigure.metrics.export.datadog.DatadogMetricsExportAutoConfiguration
org.springframework.boot.actuate.autoconfigure.metrics.export.dynatrace.DynatraceMetricsExportAutoConfiguration
org.springframework.boot.actuate.autoconfigure.metrics.export.elastic.ElasticMetricsExportAutoConfiguration
org.springframework.boot.actuate.autoconfigure.metrics.export.ganglia.GangliaMetricsExportAutoConfiguration
org.springframework.boot.actuate.autoconfigure.metrics.export.graphite.GraphiteMetricsExportAutoConfiguration
org.springframework.boot.actuate.autoconfigure.metrics.export.humio.HumioMetricsExportAutoConfiguration
org.springframework.boot.actuate.autoconfigure.metrics.export.influx.InfluxMetricsExportAutoConfiguration
org.springframework.boot.actuate.autoconfigure.metrics.export.jmx.JmxMetricsExportAutoConfiguration
org.springframework.boot.actuate.autoconfigure.metrics.export.kairos.KairosMetricsExportAutoConfiguration
org.springframework.boot.actuate.autoconfigure.metrics.export.newrelic.NewRelicMetricsExportAutoConfiguration
org.springframework.boot.actuate.autoconfigure.metrics.export.otlp.OtlpMetricsExportAutoConfiguration
org.springframework.boot.actuate.autoconfigure.metrics.export.prometheus.PrometheusMetricsExportAutoConfiguration
org.springframework.boot.actuate.autoconfigure.metrics.export.signalfx.SignalFxMetricsExportAutoConfiguration
org.springframework.boot.actuate.autoconfigure.metrics.export.simple.SimpleMetricsExportAutoConfiguration
org.springframework.boot.actuate.autoconfigure.metrics.export.stackdriver.StackdriverMetricsExportAutoConfiguration
org.springframework.boot.actuate.autoconfigure.metrics.export.statsd.StatsdMetricsExportAutoConfiguration
org.springframework.boot.actuate.autoconfigure.metrics.export.wavefront.WavefrontMetricsExportAutoConfiguration
org.springframework.boot.actuate.autoconfigure.metrics.graphql.GraphQlMetricsAutoConfiguration
org.springframework.boot.actuate.autoconfigure.metrics.integration.IntegrationMetricsAutoConfiguration
org.springframework.boot.actuate.autoconfigure.metrics.jdbc.DataSourcePoolMetricsAutoConfiguration
org.springframework.boot.actuate.autoconfigure.metrics.jersey.JerseyServerMetricsAutoConfiguration
org.springframework.boot.actuate.autoconfigure.metrics.mongo.MongoMetricsAutoConfiguration
org.springframework.boot.actuate.autoconfigure.metrics.orm.jpa.HibernateMetricsAutoConfiguration
org.springframework.boot.actuate.autoconfigure.metrics.r2dbc.ConnectionPoolMetricsAutoConfiguration
org.springframework.boot.actuate.autoconfigure.metrics.redis.LettuceMetricsAutoConfiguration
org.springframework.boot.actuate.autoconfigure.metrics.startup.StartupTimeMetricsListenerAutoConfiguration
org.springframework.boot.actuate.autoconfigure.metrics.task.TaskExecutorMetricsAutoConfiguration
org.springframework.boot.actuate.autoconfigure.metrics.web.client.HttpClientMetricsAutoConfiguration
org.springframework.boot.actuate.autoconfigure.metrics.web.jetty.JettyMetricsAutoConfiguration
org.springframework.boot.actuate.autoconfigure.metrics.web.reactive.WebFluxMetricsAutoConfiguration
org.springframework.boot.actuate.autoconfigure.metrics.web.servlet.WebMvcMetricsAutoConfiguration
org.springframework.boot.actuate.autoconfigure.metrics.web.tomcat.TomcatMetricsAutoConfiguration
org.springframework.boot.actuate.autoconfigure.data.mongo.MongoHealthContributorAutoConfiguration
org.springframework.boot.actuate.autoconfigure.data.mongo.MongoReactiveHealthContributorAutoConfiguration
org.springframework.boot.actuate.autoconfigure.neo4j.Neo4jHealthContributorAutoConfiguration
org.springframework.boot.actuate.autoconfigure.observation.ObservationAutoConfiguration
org.springframework.boot.actuate.autoconfigure.quartz.QuartzEndpointAutoConfiguration
org.springframework.boot.actuate.autoconfigure.r2dbc.ConnectionFactoryHealthContributorAutoConfiguration
org.springframework.boot.actuate.autoconfigure.data.redis.RedisHealthContributorAutoConfiguration
org.springframework.boot.actuate.autoconfigure.data.redis.RedisReactiveHealthContributorAutoConfiguration
org.springframework.boot.actuate.autoconfigure.scheduling.ScheduledTasksEndpointAutoConfiguration
org.springframework.boot.actuate.autoconfigure.security.reactive.ReactiveManagementWebSecurityAutoConfiguration
org.springframework.boot.actuate.autoconfigure.security.servlet.ManagementWebSecurityAutoConfiguration
org.springframework.boot.actuate.autoconfigure.session.SessionsEndpointAutoConfiguration
org.springframework.boot.actuate.autoconfigure.startup.StartupEndpointAutoConfiguration
org.springframework.boot.actuate.autoconfigure.system.DiskSpaceHealthContributorAutoConfiguration
org.springframework.boot.actuate.autoconfigure.trace.http.HttpTraceAutoConfiguration
org.springframework.boot.actuate.autoconfigure.trace.http.HttpTraceEndpointAutoConfiguration
org.springframework.boot.actuate.autoconfigure.tracing.BraveAutoConfiguration
org.springframework.boot.actuate.autoconfigure.tracing.MicrometerTracingAutoConfiguration
org.springframework.boot.actuate.autoconfigure.tracing.OpenTelemetryAutoConfiguration
org.springframework.boot.actuate.autoconfigure.tracing.wavefront.WavefrontTracingAutoConfiguration
org.springframework.boot.actuate.autoconfigure.tracing.zipkin.ZipkinAutoConfiguration
org.springframework.boot.actuate.autoconfigure.web.mappings.MappingsEndpointAutoConfiguration
org.springframework.boot.actuate.autoconfigure.web.reactive.ReactiveManagementContextAutoConfiguration
org.springframework.boot.actuate.autoconfigure.web.server.ManagementContextAutoConfiguration
org.springframework.boot.actuate.autoconfigure.web.servlet.ServletManagementContextAutoConfiguration

View File

@ -1,142 +0,0 @@
org.springframework.boot.autoconfigure.admin.SpringApplicationAdminJmxAutoConfiguration
org.springframework.boot.autoconfigure.aop.AopAutoConfiguration
org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration
org.springframework.boot.autoconfigure.batch.BatchAutoConfiguration
org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration
org.springframework.boot.autoconfigure.cassandra.CassandraAutoConfiguration
org.springframework.boot.autoconfigure.context.ConfigurationPropertiesAutoConfiguration
org.springframework.boot.autoconfigure.context.LifecycleAutoConfiguration
org.springframework.boot.autoconfigure.context.MessageSourceAutoConfiguration
org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration
org.springframework.boot.autoconfigure.couchbase.CouchbaseAutoConfiguration
org.springframework.boot.autoconfigure.dao.PersistenceExceptionTranslationAutoConfiguration
org.springframework.boot.autoconfigure.data.cassandra.CassandraDataAutoConfiguration
org.springframework.boot.autoconfigure.data.cassandra.CassandraReactiveDataAutoConfiguration
org.springframework.boot.autoconfigure.data.cassandra.CassandraReactiveRepositoriesAutoConfiguration
org.springframework.boot.autoconfigure.data.cassandra.CassandraRepositoriesAutoConfiguration
org.springframework.boot.autoconfigure.data.couchbase.CouchbaseDataAutoConfiguration
org.springframework.boot.autoconfigure.data.couchbase.CouchbaseReactiveDataAutoConfiguration
org.springframework.boot.autoconfigure.data.couchbase.CouchbaseReactiveRepositoriesAutoConfiguration
org.springframework.boot.autoconfigure.data.couchbase.CouchbaseRepositoriesAutoConfiguration
org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchDataAutoConfiguration
org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchRepositoriesAutoConfiguration
org.springframework.boot.autoconfigure.data.elasticsearch.ReactiveElasticsearchRepositoriesAutoConfiguration
org.springframework.boot.autoconfigure.data.jdbc.JdbcRepositoriesAutoConfiguration
org.springframework.boot.autoconfigure.data.jpa.JpaRepositoriesAutoConfiguration
org.springframework.boot.autoconfigure.data.ldap.LdapRepositoriesAutoConfiguration
org.springframework.boot.autoconfigure.data.mongo.MongoDataAutoConfiguration
org.springframework.boot.autoconfigure.data.mongo.MongoReactiveDataAutoConfiguration
org.springframework.boot.autoconfigure.data.mongo.MongoReactiveRepositoriesAutoConfiguration
org.springframework.boot.autoconfigure.data.mongo.MongoRepositoriesAutoConfiguration
org.springframework.boot.autoconfigure.data.neo4j.Neo4jDataAutoConfiguration
org.springframework.boot.autoconfigure.data.neo4j.Neo4jReactiveDataAutoConfiguration
org.springframework.boot.autoconfigure.data.neo4j.Neo4jReactiveRepositoriesAutoConfiguration
org.springframework.boot.autoconfigure.data.neo4j.Neo4jRepositoriesAutoConfiguration
org.springframework.boot.autoconfigure.data.r2dbc.R2dbcDataAutoConfiguration
org.springframework.boot.autoconfigure.data.r2dbc.R2dbcRepositoriesAutoConfiguration
org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration
org.springframework.boot.autoconfigure.data.redis.RedisReactiveAutoConfiguration
org.springframework.boot.autoconfigure.data.redis.RedisRepositoriesAutoConfiguration
org.springframework.boot.autoconfigure.data.rest.RepositoryRestMvcAutoConfiguration
org.springframework.boot.autoconfigure.data.web.SpringDataWebAutoConfiguration
org.springframework.boot.autoconfigure.elasticsearch.ElasticsearchClientAutoConfiguration
org.springframework.boot.autoconfigure.elasticsearch.ElasticsearchRestClientAutoConfiguration
org.springframework.boot.autoconfigure.elasticsearch.ReactiveElasticsearchClientAutoConfiguration
org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration
org.springframework.boot.autoconfigure.freemarker.FreeMarkerAutoConfiguration
org.springframework.boot.autoconfigure.graphql.GraphQlAutoConfiguration
org.springframework.boot.autoconfigure.graphql.data.GraphQlReactiveQueryByExampleAutoConfiguration
org.springframework.boot.autoconfigure.graphql.data.GraphQlReactiveQuerydslAutoConfiguration
org.springframework.boot.autoconfigure.graphql.data.GraphQlQueryByExampleAutoConfiguration
org.springframework.boot.autoconfigure.graphql.data.GraphQlQuerydslAutoConfiguration
org.springframework.boot.autoconfigure.graphql.reactive.GraphQlWebFluxAutoConfiguration
org.springframework.boot.autoconfigure.graphql.rsocket.GraphQlRSocketAutoConfiguration
org.springframework.boot.autoconfigure.graphql.rsocket.RSocketGraphQlClientAutoConfiguration
org.springframework.boot.autoconfigure.graphql.security.GraphQlWebFluxSecurityAutoConfiguration
org.springframework.boot.autoconfigure.graphql.security.GraphQlWebMvcSecurityAutoConfiguration
org.springframework.boot.autoconfigure.graphql.servlet.GraphQlWebMvcAutoConfiguration
org.springframework.boot.autoconfigure.groovy.template.GroovyTemplateAutoConfiguration
org.springframework.boot.autoconfigure.gson.GsonAutoConfiguration
org.springframework.boot.autoconfigure.h2.H2ConsoleAutoConfiguration
org.springframework.boot.autoconfigure.hateoas.HypermediaAutoConfiguration
org.springframework.boot.autoconfigure.hazelcast.HazelcastAutoConfiguration
org.springframework.boot.autoconfigure.hazelcast.HazelcastJpaDependencyAutoConfiguration
org.springframework.boot.autoconfigure.http.HttpMessageConvertersAutoConfiguration
org.springframework.boot.autoconfigure.http.codec.CodecsAutoConfiguration
org.springframework.boot.autoconfigure.influx.InfluxDbAutoConfiguration
org.springframework.boot.autoconfigure.info.ProjectInfoAutoConfiguration
org.springframework.boot.autoconfigure.integration.IntegrationAutoConfiguration
org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration
org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration
org.springframework.boot.autoconfigure.jdbc.JdbcTemplateAutoConfiguration
org.springframework.boot.autoconfigure.jdbc.JndiDataSourceAutoConfiguration
org.springframework.boot.autoconfigure.jdbc.XADataSourceAutoConfiguration
org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration
org.springframework.boot.autoconfigure.jersey.JerseyAutoConfiguration
org.springframework.boot.autoconfigure.jms.JmsAutoConfiguration
org.springframework.boot.autoconfigure.jmx.JmxAutoConfiguration
org.springframework.boot.autoconfigure.jms.JndiConnectionFactoryAutoConfiguration
org.springframework.boot.autoconfigure.jms.artemis.ArtemisAutoConfiguration
org.springframework.boot.autoconfigure.jooq.JooqAutoConfiguration
org.springframework.boot.autoconfigure.jsonb.JsonbAutoConfiguration
org.springframework.boot.autoconfigure.kafka.KafkaAutoConfiguration
org.springframework.boot.autoconfigure.availability.ApplicationAvailabilityAutoConfiguration
org.springframework.boot.autoconfigure.ldap.embedded.EmbeddedLdapAutoConfiguration
org.springframework.boot.autoconfigure.ldap.LdapAutoConfiguration
org.springframework.boot.autoconfigure.liquibase.LiquibaseAutoConfiguration
org.springframework.boot.autoconfigure.mail.MailSenderAutoConfiguration
org.springframework.boot.autoconfigure.mail.MailSenderValidatorAutoConfiguration
org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration
org.springframework.boot.autoconfigure.mongo.MongoReactiveAutoConfiguration
org.springframework.boot.autoconfigure.mustache.MustacheAutoConfiguration
org.springframework.boot.autoconfigure.neo4j.Neo4jAutoConfiguration
org.springframework.boot.autoconfigure.netty.NettyAutoConfiguration
org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration
org.springframework.boot.autoconfigure.quartz.QuartzAutoConfiguration
org.springframework.boot.autoconfigure.r2dbc.R2dbcAutoConfiguration
org.springframework.boot.autoconfigure.r2dbc.R2dbcTransactionManagerAutoConfiguration
org.springframework.boot.autoconfigure.rsocket.RSocketMessagingAutoConfiguration
org.springframework.boot.autoconfigure.rsocket.RSocketRequesterAutoConfiguration
org.springframework.boot.autoconfigure.rsocket.RSocketServerAutoConfiguration
org.springframework.boot.autoconfigure.rsocket.RSocketStrategiesAutoConfiguration
org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration
org.springframework.boot.autoconfigure.security.servlet.UserDetailsServiceAutoConfiguration
org.springframework.boot.autoconfigure.security.servlet.SecurityFilterAutoConfiguration
org.springframework.boot.autoconfigure.security.reactive.ReactiveSecurityAutoConfiguration
org.springframework.boot.autoconfigure.security.reactive.ReactiveUserDetailsServiceAutoConfiguration
org.springframework.boot.autoconfigure.security.rsocket.RSocketSecurityAutoConfiguration
org.springframework.boot.autoconfigure.security.saml2.Saml2RelyingPartyAutoConfiguration
org.springframework.boot.autoconfigure.sendgrid.SendGridAutoConfiguration
org.springframework.boot.autoconfigure.session.SessionAutoConfiguration
org.springframework.boot.autoconfigure.security.oauth2.client.servlet.OAuth2ClientAutoConfiguration
org.springframework.boot.autoconfigure.security.oauth2.client.reactive.ReactiveOAuth2ClientAutoConfiguration
org.springframework.boot.autoconfigure.security.oauth2.resource.servlet.OAuth2ResourceServerAutoConfiguration
org.springframework.boot.autoconfigure.security.oauth2.resource.reactive.ReactiveOAuth2ResourceServerAutoConfiguration
org.springframework.boot.autoconfigure.sql.init.SqlInitializationAutoConfiguration
org.springframework.boot.autoconfigure.task.TaskExecutionAutoConfiguration
org.springframework.boot.autoconfigure.task.TaskSchedulingAutoConfiguration
org.springframework.boot.autoconfigure.thymeleaf.ThymeleafAutoConfiguration
org.springframework.boot.autoconfigure.transaction.TransactionAutoConfiguration
org.springframework.boot.autoconfigure.transaction.jta.JtaAutoConfiguration
org.springframework.boot.autoconfigure.validation.ValidationAutoConfiguration
org.springframework.boot.autoconfigure.web.client.RestTemplateAutoConfiguration
org.springframework.boot.autoconfigure.web.embedded.EmbeddedWebServerFactoryCustomizerAutoConfiguration
org.springframework.boot.autoconfigure.web.reactive.HttpHandlerAutoConfiguration
org.springframework.boot.autoconfigure.web.reactive.ReactiveMultipartAutoConfiguration
org.springframework.boot.autoconfigure.web.reactive.ReactiveWebServerFactoryAutoConfiguration
org.springframework.boot.autoconfigure.web.reactive.WebFluxAutoConfiguration
org.springframework.boot.autoconfigure.web.reactive.WebSessionIdResolverAutoConfiguration
org.springframework.boot.autoconfigure.web.reactive.error.ErrorWebFluxAutoConfiguration
org.springframework.boot.autoconfigure.web.reactive.function.client.ClientHttpConnectorAutoConfiguration
org.springframework.boot.autoconfigure.web.reactive.function.client.WebClientAutoConfiguration
org.springframework.boot.autoconfigure.web.servlet.DispatcherServletAutoConfiguration
org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration
org.springframework.boot.autoconfigure.web.servlet.error.ErrorMvcAutoConfiguration
org.springframework.boot.autoconfigure.web.servlet.HttpEncodingAutoConfiguration
org.springframework.boot.autoconfigure.web.servlet.MultipartAutoConfiguration
org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration
org.springframework.boot.autoconfigure.websocket.reactive.WebSocketReactiveAutoConfiguration
org.springframework.boot.autoconfigure.websocket.servlet.WebSocketServletAutoConfiguration
org.springframework.boot.autoconfigure.websocket.servlet.WebSocketMessagingAutoConfiguration
org.springframework.boot.autoconfigure.webservices.WebServicesAutoConfiguration
org.springframework.boot.autoconfigure.webservices.client.WebServiceTemplateAutoConfiguration

View File

@ -1,4 +0,0 @@
org.springframework.boot.devtools.autoconfigure.DevToolsDataSourceAutoConfiguration
org.springframework.boot.devtools.autoconfigure.DevToolsR2dbcAutoConfiguration
org.springframework.boot.devtools.autoconfigure.LocalDevToolsAutoConfiguration
org.springframework.boot.devtools.autoconfigure.RemoteDevToolsAutoConfiguration

View File

@ -16,7 +16,7 @@ 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 `@AutoConfiguration` 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).
You can browse the source code of {spring-boot-autoconfigure-module-code}[`spring-boot-autoconfigure`] to see the `@AutoConfiguration` classes that Spring provides.
@ -34,6 +34,9 @@ The file should list your configuration classes, with one class name per line, a
TIP: You can add comments to the imports file using the `#` character.
The auto-configuration imports file can be generated automatically using an annotation processor to collect all classes annotated with `@AutoConfiguration`.
See <<features#features.developing-auto-configuration.autoconfigure-processor,Using the Auto-configuration Annotation Processor>> for more information.
NOTE: Auto-configurations must be loaded _only_ by being named in the imports file.
Make sure that they are defined in a specific package space and that they are never the target of component scanning.
Furthermore, auto-configuration classes should not enable component scanning to find additional components.
@ -260,8 +263,32 @@ If you do it that way, the library is not provided and, by default, Spring Boot
Spring Boot uses an annotation processor to collect the conditions on auto-configurations in a metadata file (`META-INF/spring-autoconfigure-metadata.properties`).
If that file is present, it is used to eagerly filter auto-configurations that do not match, which will improve startup time.
See <<features#features.developing-auto-configuration.autoconfigure-processor,Using the Auto-configuration Annotation Processor>> for more information.
When building with Maven, it is recommended to add the following dependency in a module that contains auto-configurations:
[[features.developing-auto-configuration.custom-starter.starter-module]]
==== Starter Module
The starter is really an empty jar.
Its only purpose is to provide the necessary dependencies to work with the library.
You can think of it as an opinionated view of what is required to get started.
Do not make assumptions about the project in which your starter is added.
If the library you are auto-configuring typically requires other starters, mention them as well.
Providing a proper set of _default_ dependencies may be hard if the number of optional dependencies is high, as you should avoid including dependencies that are unnecessary for a typical usage of the library.
In other words, you should not include optional dependencies.
NOTE: Either way, your starter must reference the core Spring Boot starter (`spring-boot-starter`) directly or indirectly (there is no need to add it if your starter relies on another starter).
If a project is created with only your custom starter, Spring Boot's core features will be honoured by the presence of the core starter.
[[features.developing-auto-configuration.autoconfigure-processor]]
=== Using the Auto-configuration Annotation Processor
An auto-configuration annotation processor can be added to a project to automate the creation of the <<features.developing-auto-configuration.locating-auto-configuration-candidates,auto-configuration imports file>> and the <<features.developing-auto-configuration.custom-starter.autoconfigure-module,auto-configurations conditions metadata file>>.
When building with Maven, add the following dependency in a module that contains auto-configurations:
[source,xml,indent=0,subs="verbatim"]
----
@ -305,18 +332,3 @@ With Gradle, the dependency should be declared in the `annotationProcessor` conf
}
----
[[features.developing-auto-configuration.custom-starter.starter-module]]
==== Starter Module
The starter is really an empty jar.
Its only purpose is to provide the necessary dependencies to work with the library.
You can think of it as an opinionated view of what is required to get started.
Do not make assumptions about the project in which your starter is added.
If the library you are auto-configuring typically requires other starters, mention them as well.
Providing a proper set of _default_ dependencies may be hard if the number of optional dependencies is high, as you should avoid including dependencies that are unnecessary for a typical usage of the library.
In other words, you should not include optional dependencies.
NOTE: Either way, your starter must reference the core Spring Boot starter (`spring-boot-starter`) directly or indirectly (there is no need to add it if your starter relies on another starter).
If a project is created with only your custom starter, Spring Boot's core features will be honoured by the presence of the core starter.

View File

@ -0,0 +1,89 @@
/*
* 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.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.autoconfigureprocessor;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import javax.annotation.processing.AbstractProcessor;
import javax.annotation.processing.Filer;
import javax.annotation.processing.RoundEnvironment;
import javax.annotation.processing.SupportedAnnotationTypes;
import javax.lang.model.SourceVersion;
import javax.lang.model.element.Element;
import javax.lang.model.element.TypeElement;
import javax.tools.FileObject;
import javax.tools.StandardLocation;
/**
* Annotation processor to generate a
* {@code META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports}
* file from {@code @AutoConfiguration} annotations.
*
* @author Scott Frederick
* @since 3.0.0
*/
@SupportedAnnotationTypes({ "org.springframework.boot.autoconfigure.AutoConfiguration" })
public class AutoConfigurationImportsAnnotationProcessor extends AbstractProcessor {
static final String IMPORTS_FILE_PATH = "META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports";
private final List<String> qualifiedClassNames = new ArrayList<>();
@Override
public SourceVersion getSupportedSourceVersion() {
return SourceVersion.latestSupported();
}
@Override
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
for (TypeElement annotation : annotations) {
Set<? extends Element> elements = roundEnv.getElementsAnnotatedWith(annotation);
for (Element element : elements) {
this.qualifiedClassNames.add(element.asType().toString());
}
}
if (roundEnv.processingOver()) {
try {
writeImportsFile();
}
catch (IOException ex) {
throw new IllegalStateException("Failed to write auto-configuration imports file", ex);
}
}
return false;
}
private void writeImportsFile() throws IOException {
if (!this.qualifiedClassNames.isEmpty()) {
Filer filer = this.processingEnv.getFiler();
FileObject file = filer.createResource(StandardLocation.CLASS_OUTPUT, "", IMPORTS_FILE_PATH);
try (Writer writer = new OutputStreamWriter(file.openOutputStream(), StandardCharsets.UTF_8)) {
for (String className : this.qualifiedClassNames) {
writer.append(className);
writer.append(System.lineSeparator());
}
}
}
}
}

View File

@ -1 +1,2 @@
org.springframework.boot.autoconfigureprocessor.AutoConfigureAnnotationProcessor,aggregating
org.springframework.boot.autoconfigureprocessor.AutoConfigureAnnotationProcessor,aggregating
org.springframework.boot.autoconfigureprocessor.AutoConfigurationImportsAnnotationProcessor,aggregating

View File

@ -1 +1,2 @@
org.springframework.boot.autoconfigureprocessor.AutoConfigureAnnotationProcessor
org.springframework.boot.autoconfigureprocessor.AutoConfigurationImportsAnnotationProcessor

View File

@ -0,0 +1,86 @@
/*
* 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.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.autoconfigureprocessor;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.List;
import java.util.stream.Collectors;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;
import org.springframework.boot.testsupport.compiler.TestCompiler;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Tests for {@link TestAutoConfigurationImportsAnnotationProcessor}.
*
* @author Scott Frederick
*/
class AutoConfigurationImportsAnnotationProcessorTests {
@TempDir
File tempDir;
private TestCompiler compiler;
@BeforeEach
void createCompiler() throws IOException {
this.compiler = new TestCompiler(this.tempDir);
}
@Test
void annotatedClasses() throws Exception {
List<String> classes = compile(TestAutoConfigurationConfiguration.class,
TestAutoConfigurationOnlyConfiguration.class);
assertThat(classes).hasSize(2);
assertThat(classes).containsExactly(
"org.springframework.boot.autoconfigureprocessor.TestAutoConfigurationConfiguration",
"org.springframework.boot.autoconfigureprocessor.TestAutoConfigurationOnlyConfiguration");
}
@Test
void notAnnotatedClasses() throws Exception {
List<String> classes = compile(TestAutoConfigurationImportsAnnotationProcessor.class);
assertThat(classes).isNull();
}
private List<String> compile(Class<?>... types) throws IOException {
TestAutoConfigurationImportsAnnotationProcessor processor = new TestAutoConfigurationImportsAnnotationProcessor();
this.compiler.getTask(types).call(processor);
return getWrittenImports();
}
private List<String> getWrittenImports() throws IOException {
File file = getWrittenFile();
if (!file.exists()) {
return null;
}
BufferedReader reader = new BufferedReader(new FileReader(file));
return reader.lines().collect(Collectors.toList());
}
private File getWrittenFile() {
return new File(this.tempDir, AutoConfigurationImportsAnnotationProcessor.IMPORTS_FILE_PATH);
}
}

View File

@ -0,0 +1,29 @@
/*
* 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.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.autoconfigureprocessor;
import javax.annotation.processing.SupportedAnnotationTypes;
/**
* An extension of {@link AutoConfigurationImportsAnnotationProcessor} used for testing.
*
* @author Scott Frederick
*/
@SupportedAnnotationTypes({ "org.springframework.boot.autoconfigureprocessor.TestAutoConfiguration" })
public class TestAutoConfigurationImportsAnnotationProcessor extends AutoConfigurationImportsAnnotationProcessor {
}

View File

@ -17,6 +17,8 @@ configurations.all {
}
dependencies {
annotationProcessor(project(":spring-boot-project:spring-boot-tools:spring-boot-autoconfigure-processor"))
implementation(project(":spring-boot-project:spring-boot-starters:spring-boot-starter-web")) {
exclude group: "org.hibernate.validator"
}

View File

@ -21,6 +21,7 @@ dependencies {
testRepository(project(path: ":spring-boot-project:spring-boot-dependencies", configuration: "mavenRepository"))
testRepository(project(path: ":spring-boot-project:spring-boot-tools:spring-boot-gradle-plugin", configuration: "mavenRepository"))
testRepository(project(path: ":spring-boot-project:spring-boot-tools:spring-boot-autoconfigure-processor", configuration: "mavenRepository"))
testRepository(project(path: ":spring-boot-project:spring-boot-starters:spring-boot-starter", configuration: "mavenRepository"))
testRepository(project(path: ":spring-boot-project:spring-boot-starters:spring-boot-starter-jetty", configuration: "mavenRepository"))
testRepository(project(path: ":spring-boot-project:spring-boot-starters:spring-boot-starter-json", configuration: "mavenRepository"))

View File

@ -49,6 +49,8 @@ tasks.register("resourcesJar", Jar) { jar ->
}
dependencies {
annotationProcessor("org.springframework.boot:spring-boot-autoconfigure-processor")
compileOnly("org.eclipse.jetty:jetty-server")
implementation("org.springframework.boot:spring-boot-starter")