Commit b80620fe authored by Stephane Nicoll's avatar Stephane Nicoll

Revert "Group auto-configuration import selectors together"

This reverts commit 26d9c261
parent 282bd9f0
...@@ -16,16 +16,14 @@ ...@@ -16,16 +16,14 @@
package org.springframework.boot.autoconfigure; package org.springframework.boot.autoconfigure;
import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet; import java.util.LinkedHashSet;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
...@@ -90,23 +88,24 @@ public class AutoConfigurationImportSelector ...@@ -90,23 +88,24 @@ public class AutoConfigurationImportSelector
if (!isEnabled(annotationMetadata)) { if (!isEnabled(annotationMetadata)) {
return NO_IMPORTS; return NO_IMPORTS;
} }
AutoConfigurationMetadata autoConfigurationMetadata = AutoConfigurationMetadataLoader try {
.loadMetadata(this.beanClassLoader); AutoConfigurationMetadata autoConfigurationMetadata = AutoConfigurationMetadataLoader
AnnotationAttributes attributes = getAttributes(annotationMetadata); .loadMetadata(this.beanClassLoader);
List<String> configurations = getCandidateConfigurations(annotationMetadata, AnnotationAttributes attributes = getAttributes(annotationMetadata);
attributes); List<String> configurations = getCandidateConfigurations(annotationMetadata,
configurations = removeDuplicates(configurations); attributes);
Set<String> exclusions = getExclusions(annotationMetadata, attributes); configurations = removeDuplicates(configurations);
checkExcludedClasses(configurations, exclusions); configurations = sort(configurations, autoConfigurationMetadata);
configurations.removeAll(exclusions); Set<String> exclusions = getExclusions(annotationMetadata, attributes);
configurations = filter(configurations, autoConfigurationMetadata); checkExcludedClasses(configurations, exclusions);
fireAutoConfigurationImportEvents(configurations, exclusions); configurations.removeAll(exclusions);
return StringUtils.toStringArray(configurations); configurations = filter(configurations, autoConfigurationMetadata);
} fireAutoConfigurationImportEvents(configurations, exclusions);
return StringUtils.toStringArray(configurations);
@Override }
public Class<? extends Group> getImportGroup() { catch (IOException ex) {
return AutoConfigurationGroup.class; throw new IllegalStateException(ex);
}
} }
protected boolean isEnabled(AnnotationMetadata metadata) { protected boolean isEnabled(AnnotationMetadata metadata) {
...@@ -227,6 +226,13 @@ public class AutoConfigurationImportSelector ...@@ -227,6 +226,13 @@ public class AutoConfigurationImportSelector
return (excludes == null ? Collections.emptyList() : Arrays.asList(excludes)); return (excludes == null ? Collections.emptyList() : Arrays.asList(excludes));
} }
private List<String> sort(List<String> configurations,
AutoConfigurationMetadata autoConfigurationMetadata) throws IOException {
configurations = new AutoConfigurationSorter(getMetadataReaderFactory(),
autoConfigurationMetadata).getInPriorityOrder(configurations);
return configurations;
}
private List<String> filter(List<String> configurations, private List<String> filter(List<String> configurations,
AutoConfigurationMetadata autoConfigurationMetadata) { AutoConfigurationMetadata autoConfigurationMetadata) {
long startTime = System.nanoTime(); long startTime = System.nanoTime();
...@@ -266,6 +272,17 @@ public class AutoConfigurationImportSelector ...@@ -266,6 +272,17 @@ public class AutoConfigurationImportSelector
this.beanClassLoader); this.beanClassLoader);
} }
private MetadataReaderFactory getMetadataReaderFactory() {
try {
return getBeanFactory().getBean(
SharedMetadataReaderFactoryContextInitializer.BEAN_NAME,
MetadataReaderFactory.class);
}
catch (NoSuchBeanDefinitionException ex) {
return new CachingMetadataReaderFactory(this.resourceLoader);
}
}
protected final <T> List<T> removeDuplicates(List<T> list) { protected final <T> List<T> removeDuplicates(List<T> list) {
return new ArrayList<>(new LinkedHashSet<>(list)); return new ArrayList<>(new LinkedHashSet<>(list));
} }
...@@ -353,71 +370,4 @@ public class AutoConfigurationImportSelector ...@@ -353,71 +370,4 @@ public class AutoConfigurationImportSelector
return Ordered.LOWEST_PRECEDENCE - 1; return Ordered.LOWEST_PRECEDENCE - 1;
} }
private static class AutoConfigurationGroup implements DeferredImportSelector.Group,
BeanClassLoaderAware, BeanFactoryAware, ResourceLoaderAware {
private ClassLoader beanClassLoader;
private BeanFactory beanFactory;
private ResourceLoader resourceLoader;
private final Map<String, AnnotationMetadata> entries = new LinkedHashMap<>();
@Override
public void setBeanClassLoader(ClassLoader classLoader) {
this.beanClassLoader = classLoader;
}
@Override
public void setBeanFactory(BeanFactory beanFactory) {
this.beanFactory = beanFactory;
}
@Override
public void setResourceLoader(ResourceLoader resourceLoader) {
this.resourceLoader = resourceLoader;
}
@Override
public void process(AnnotationMetadata annotationMetadata,
DeferredImportSelector deferredImportSelector) {
String[] imports = deferredImportSelector.selectImports(annotationMetadata);
for (String importClassName : imports) {
this.entries.put(importClassName, annotationMetadata);
}
}
@Override
public Iterable<Entry> selectImports() {
return sortAutoConfigurations().stream().map((importClassName) ->
new Entry(this.entries.get(importClassName), importClassName))
.collect(Collectors.toList());
}
private List<String> sortAutoConfigurations() {
List<String> autoConfigurations = new ArrayList<>(this.entries.keySet());
if (this.entries.size() <= 1) {
return autoConfigurations;
}
AutoConfigurationMetadata autoConfigurationMetadata = AutoConfigurationMetadataLoader
.loadMetadata(this.beanClassLoader);
return new AutoConfigurationSorter(getMetadataReaderFactory(),
autoConfigurationMetadata).getInPriorityOrder(autoConfigurations);
}
private MetadataReaderFactory getMetadataReaderFactory() {
try {
return this.beanFactory.getBean(
SharedMetadataReaderFactoryContextInitializer.BEAN_NAME,
MetadataReaderFactory.class);
}
catch (NoSuchBeanDefinitionException ex) {
return new CachingMetadataReaderFactory(this.resourceLoader);
}
}
}
} }
/*
* Copyright 2012-2018 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
*
* http://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.autoconfigure;
import java.util.ArrayList;
import java.util.List;
import org.junit.Test;
import org.springframework.boot.test.context.assertj.AssertableApplicationContext;
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
import org.springframework.context.annotation.Configuration;
import org.springframework.util.ClassUtils;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Integration tests for {@link AutoConfigurationImportSelector}.
*
* @author Stephane Nicoll
*/
public class AutoConfigurationImportSelectorIntegrationTests {
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner();
@Test
public void singleSelectorWithNoImports() {
this.contextRunner.withUserConfiguration(NoConfig.class)
.run((context) ->
assertThat(getImportedConfigBeans(context)).isEmpty());
}
@Test
public void singleSelector() {
this.contextRunner.withUserConfiguration(SingleConfig.class)
.run((context) -> {
assertThat(getImportedConfigBeans(context)).containsExactly(
"ConfigC");
});
}
@Test
public void multipleSelectorShouldMergeAndSortCorrectly() {
this.contextRunner.withUserConfiguration(Config.class, AnotherConfig.class)
.run((context) -> {
assertThat(getImportedConfigBeans(context)).containsExactly(
"ConfigA", "ConfigB", "ConfigC", "ConfigD");
});
}
@Test
public void multipleSelectorWithRedundantImportsShouldMergeAndSortCorrectly() {
this.contextRunner.withUserConfiguration(SingleConfig.class, Config.class,
AnotherConfig.class).run((context) -> {
assertThat(getImportedConfigBeans(context)).containsExactly(
"ConfigA", "ConfigB", "ConfigC", "ConfigD");
});
}
private List<String> getImportedConfigBeans(AssertableApplicationContext context) {
String shortName = ClassUtils.getShortName(
AutoConfigurationImportSelectorIntegrationTests.class);
int beginIndex = shortName.length() + 1;
List<String> orderedConfigBeans = new ArrayList<>();
for (String bean : context.getBeanDefinitionNames()) {
if (bean.contains("$Config")) {
String shortBeanName = ClassUtils.getShortName(bean);
orderedConfigBeans.add(shortBeanName.substring(beginIndex));
}
}
return orderedConfigBeans;
}
@ImportAutoConfiguration
static class NoConfig {
}
@ImportAutoConfiguration(ConfigC.class)
static class SingleConfig {
}
@ImportAutoConfiguration({ ConfigD.class, ConfigB.class })
static class Config {
}
@ImportAutoConfiguration({ ConfigC.class, ConfigA.class })
static class AnotherConfig {
}
@Configuration
static class ConfigA {
}
@Configuration
@AutoConfigureAfter(ConfigA.class)
@AutoConfigureBefore(ConfigC.class)
static class ConfigB {
}
@Configuration
static class ConfigC {
}
@Configuration
@AutoConfigureAfter(ConfigC.class)
static class ConfigD {
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment