Exclude auto-configurations via property
Add `spring.autoconfigure.exclude` to control the list of auto-configuration classes to exclude via configuration. Merge the exclusions defined on the `@EnableAutoConfiguration` or `@SpringBooApplication` if any. Closes gh-2435
This commit is contained in:
parent
da60c94d57
commit
eb5d92f3f0
|
@ -44,8 +44,9 @@ import org.springframework.core.io.support.SpringFactoriesLoader;
|
|||
* Auto-configuration tries to be as intelligent as possible and will back-away as you
|
||||
* define more of your own configuration. You can always manually {@link #exclude()} any
|
||||
* configuration that you never want to apply (use {@link #excludeName()} if you don't
|
||||
* have access to them). Auto-configuration is always applied after user-defined beans
|
||||
* have been registered.
|
||||
* have access to them). You can also exclude them via the
|
||||
* {@code spring.autoconfigure.exclude} property. Auto-configuration is always applied
|
||||
* after user-defined beans have been registered.
|
||||
* <p>
|
||||
* The package of the class that is annotated with {@code @EnableAutoConfiguration} has
|
||||
* specific significance and is often used as a 'default'. For example, it will be used
|
||||
|
|
|
@ -19,6 +19,7 @@ package org.springframework.boot.autoconfigure;
|
|||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
@ -29,11 +30,14 @@ import org.springframework.beans.factory.BeanFactory;
|
|||
import org.springframework.beans.factory.BeanFactoryAware;
|
||||
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionEvaluationReport;
|
||||
import org.springframework.boot.bind.RelaxedPropertyResolver;
|
||||
import org.springframework.context.EnvironmentAware;
|
||||
import org.springframework.context.ResourceLoaderAware;
|
||||
import org.springframework.context.annotation.DeferredImportSelector;
|
||||
import org.springframework.core.Ordered;
|
||||
import org.springframework.core.annotation.AnnotationAttributes;
|
||||
import org.springframework.core.annotation.Order;
|
||||
import org.springframework.core.env.Environment;
|
||||
import org.springframework.core.io.ResourceLoader;
|
||||
import org.springframework.core.io.support.SpringFactoriesLoader;
|
||||
import org.springframework.core.type.AnnotationMetadata;
|
||||
|
@ -50,10 +54,12 @@ import org.springframework.util.Assert;
|
|||
*/
|
||||
@Order(Ordered.LOWEST_PRECEDENCE - 1)
|
||||
class EnableAutoConfigurationImportSelector implements DeferredImportSelector,
|
||||
BeanClassLoaderAware, ResourceLoaderAware, BeanFactoryAware {
|
||||
BeanClassLoaderAware, ResourceLoaderAware, BeanFactoryAware, EnvironmentAware {
|
||||
|
||||
private ConfigurableListableBeanFactory beanFactory;
|
||||
|
||||
private Environment environment;
|
||||
|
||||
private ClassLoader beanClassLoader;
|
||||
|
||||
private ResourceLoader resourceLoader;
|
||||
|
@ -78,6 +84,7 @@ class EnableAutoConfigurationImportSelector implements DeferredImportSelector,
|
|||
Set<String> excluded = new LinkedHashSet<String>();
|
||||
excluded.addAll(Arrays.asList(attributes.getStringArray("exclude")));
|
||||
excluded.addAll(Arrays.asList(attributes.getStringArray("excludeName")));
|
||||
excluded.addAll(getExcludeAutoConfigurationsProperty());
|
||||
factories.removeAll(excluded);
|
||||
ConditionEvaluationReport.get(this.beanFactory).recordExclusions(excluded);
|
||||
ConditionEvaluationReport.get(this.beanFactory).recordEvaluationCandidates(
|
||||
|
@ -94,6 +101,16 @@ class EnableAutoConfigurationImportSelector implements DeferredImportSelector,
|
|||
}
|
||||
}
|
||||
|
||||
private List<String> getExcludeAutoConfigurationsProperty() {
|
||||
RelaxedPropertyResolver resolver = new RelaxedPropertyResolver(this.environment,
|
||||
"spring.autoconfigure.");
|
||||
String[] value = resolver.getProperty("exclude", String[].class);
|
||||
if (value != null) {
|
||||
return Arrays.asList(value);
|
||||
}
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBeanClassLoader(ClassLoader classLoader) {
|
||||
this.beanClassLoader = classLoader;
|
||||
|
@ -110,4 +127,9 @@ class EnableAutoConfigurationImportSelector implements DeferredImportSelector,
|
|||
this.beanFactory = (ConfigurableListableBeanFactory) beanFactory;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setEnvironment(Environment environment) {
|
||||
this.environment = environment;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -29,6 +29,11 @@
|
|||
"description": "JMX name of the application admin MBean.",
|
||||
"defaultValue": "org.springframework.boot:type=Admin,name=SpringApplication"
|
||||
},
|
||||
{
|
||||
"name": "spring.autoconfigure.exclude",
|
||||
"type": "java.lang.Class[]",
|
||||
"description": "Auto-configuration classes to exclude."
|
||||
},
|
||||
{
|
||||
"name": "spring.batch.job.enabled",
|
||||
"type": "java.lang.Boolean",
|
||||
|
|
|
@ -18,6 +18,7 @@ package org.springframework.boot.autoconfigure;
|
|||
|
||||
import java.util.List;
|
||||
|
||||
import org.flywaydb.core.internal.util.StringUtils;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
@ -27,11 +28,13 @@ import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
|||
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionEvaluationReport;
|
||||
import org.springframework.boot.autoconfigure.freemarker.FreeMarkerAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.thymeleaf.ThymeleafAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.velocity.VelocityAutoConfiguration;
|
||||
import org.springframework.core.annotation.AnnotationAttributes;
|
||||
import org.springframework.core.io.DefaultResourceLoader;
|
||||
import org.springframework.core.io.support.SpringFactoriesLoader;
|
||||
import org.springframework.core.type.AnnotationMetadata;
|
||||
import org.springframework.mock.env.MockEnvironment;
|
||||
|
||||
import static org.hamcrest.Matchers.contains;
|
||||
import static org.hamcrest.Matchers.containsInAnyOrder;
|
||||
|
@ -54,6 +57,8 @@ public class EnableAutoConfigurationImportSelectorTests {
|
|||
|
||||
private final ConfigurableListableBeanFactory beanFactory = new DefaultListableBeanFactory();
|
||||
|
||||
private final MockEnvironment environment = new MockEnvironment();
|
||||
|
||||
@Mock
|
||||
private AnnotationMetadata annotationMetadata;
|
||||
|
||||
|
@ -63,12 +68,13 @@ public class EnableAutoConfigurationImportSelectorTests {
|
|||
@Before
|
||||
public void configureImportSelector() {
|
||||
this.importSelector.setBeanFactory(this.beanFactory);
|
||||
this.importSelector.setEnvironment(this.environment);
|
||||
this.importSelector.setResourceLoader(new DefaultResourceLoader());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void importsAreSelected() {
|
||||
configureExclusions(new String[0], new String[0]);
|
||||
configureExclusions(new String[0], new String[0], new String[0]);
|
||||
String[] imports = this.importSelector.selectImports(this.annotationMetadata);
|
||||
assertThat(
|
||||
imports.length,
|
||||
|
@ -82,7 +88,7 @@ public class EnableAutoConfigurationImportSelectorTests {
|
|||
@Test
|
||||
public void classExclusionsAreApplied() {
|
||||
configureExclusions(new String[] { FreeMarkerAutoConfiguration.class.getName() },
|
||||
new String[0]);
|
||||
new String[0], new String[0]);
|
||||
String[] imports = this.importSelector.selectImports(this.annotationMetadata);
|
||||
assertThat(imports.length,
|
||||
is(equalTo(getAutoConfigurationClassNames().size() - 1)));
|
||||
|
@ -93,7 +99,7 @@ public class EnableAutoConfigurationImportSelectorTests {
|
|||
@Test
|
||||
public void classNamesExclusionsAreApplied() {
|
||||
configureExclusions(new String[0],
|
||||
new String[] { VelocityAutoConfiguration.class.getName() });
|
||||
new String[] { VelocityAutoConfiguration.class.getName() }, new String[0]);
|
||||
String[] imports = this.importSelector.selectImports(this.annotationMetadata);
|
||||
assertThat(imports.length,
|
||||
is(equalTo(getAutoConfigurationClassNames().size() - 1)));
|
||||
|
@ -102,9 +108,22 @@ public class EnableAutoConfigurationImportSelectorTests {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void bothExclusionsAreApplied() {
|
||||
configureExclusions(new String[] { VelocityAutoConfiguration.class.getName() },
|
||||
new String[] { FreeMarkerAutoConfiguration.class.getName() });
|
||||
public void propertyExclusionsAreApplied() {
|
||||
configureExclusions(new String[0], new String[0], new String[] {
|
||||
FreeMarkerAutoConfiguration.class.getName()});
|
||||
String[] imports = this.importSelector.selectImports(this.annotationMetadata);
|
||||
assertThat(imports.length,
|
||||
is(equalTo(getAutoConfigurationClassNames().size() - 1)));
|
||||
assertThat(ConditionEvaluationReport.get(this.beanFactory).getExclusions(),
|
||||
contains(FreeMarkerAutoConfiguration.class.getName()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void severalPropertyExclusionsAreApplied() {
|
||||
configureExclusions(new String[0], new String[0], new String[] {
|
||||
FreeMarkerAutoConfiguration.class.getName(), VelocityAutoConfiguration
|
||||
.class.getName()});
|
||||
|
||||
String[] imports = this.importSelector.selectImports(this.annotationMetadata);
|
||||
assertThat(imports.length,
|
||||
is(equalTo(getAutoConfigurationClassNames().size() - 2)));
|
||||
|
@ -114,7 +133,23 @@ public class EnableAutoConfigurationImportSelectorTests {
|
|||
VelocityAutoConfiguration.class.getName()));
|
||||
}
|
||||
|
||||
private void configureExclusions(String[] classExclusion, String[] nameExclusion) {
|
||||
@Test
|
||||
public void combinedExclusionsAreApplied() {
|
||||
configureExclusions(new String[] { VelocityAutoConfiguration.class.getName() },
|
||||
new String[] { FreeMarkerAutoConfiguration.class.getName() },
|
||||
new String[] { ThymeleafAutoConfiguration.class.getName() });
|
||||
String[] imports = this.importSelector.selectImports(this.annotationMetadata);
|
||||
assertThat(imports.length,
|
||||
is(equalTo(getAutoConfigurationClassNames().size() - 3)));
|
||||
assertThat(
|
||||
ConditionEvaluationReport.get(this.beanFactory).getExclusions(),
|
||||
containsInAnyOrder(FreeMarkerAutoConfiguration.class.getName(),
|
||||
VelocityAutoConfiguration.class.getName(),
|
||||
ThymeleafAutoConfiguration.class.getName()));
|
||||
}
|
||||
|
||||
private void configureExclusions(String[] classExclusion, String[] nameExclusion,
|
||||
String[] propertyExclusion) {
|
||||
given(
|
||||
this.annotationMetadata.getAnnotationAttributes(
|
||||
EnableAutoConfiguration.class.getName(), true)).willReturn(
|
||||
|
@ -123,6 +158,11 @@ public class EnableAutoConfigurationImportSelectorTests {
|
|||
classExclusion);
|
||||
given(this.annotationAttributes.getStringArray("excludeName")).willReturn(
|
||||
nameExclusion);
|
||||
if (propertyExclusion.length > 0) {
|
||||
String value = StringUtils.arrayToCommaDelimitedString(propertyExclusion);
|
||||
this.environment.setProperty("spring.autoconfigure.exclude",
|
||||
value);
|
||||
}
|
||||
}
|
||||
|
||||
private List<String> getAutoConfigurationClassNames() {
|
||||
|
|
|
@ -45,6 +45,9 @@ content into your application; rather pick only the properties that you need.
|
|||
spring.main.show-banner=true
|
||||
spring.main....= # see class for all properties
|
||||
|
||||
# AUTO-CONFIGURATION
|
||||
spring.autoconfigure.exclude= # comma-separated list of auto-configuration classes to exclude
|
||||
|
||||
# ADMIN ({sc-spring-boot-autoconfigure}/admin/SpringApplicationAdminJmxAutoConfiguration.{sc-ext}[SpringApplicationAdminJmxAutoConfiguration])
|
||||
spring.application.admin.enabled=false # enable admin features for the application
|
||||
spring.application.admin.jmx-name=org.springframework.boot:type=Admin,name=SpringApplication # JMX name of the application admin MBean
|
||||
|
|
|
@ -602,7 +602,7 @@ report to the console.
|
|||
|
||||
|
||||
|
||||
[[using-boot-disabling-specific-auto-configutation]]
|
||||
[[using-boot-disabling-specific-auto-configuration]]
|
||||
=== Disabling specific auto-configuration
|
||||
If you find that specific auto-configure classes are being applied that you don't want,
|
||||
you can use the exclude attribute of `@EnableAutoConfiguration` to disable them.
|
||||
|
@ -619,7 +619,12 @@ you can use the exclude attribute of `@EnableAutoConfiguration` to disable them.
|
|||
}
|
||||
----
|
||||
|
||||
If the class is not on the classpath, you can use the `excludeName` attribute of
|
||||
the annotation and specify the fully qualified name instead. Finally, you can also
|
||||
control the list of auto-configuration classes to excludes via the
|
||||
`spring.autoconfigure.exclude` property.
|
||||
|
||||
TIP: You can define exclusions both at the annotation level and using the property.
|
||||
|
||||
[[using-boot-spring-beans-and-dependency-injection]]
|
||||
== Spring Beans and dependency injection
|
||||
|
|
Loading…
Reference in New Issue