Additional configuration classes get detected when imported through XML or registrars

Issue: SPR-11430
Issue: SPR-11723
This commit is contained in:
Juergen Hoeller
2014-08-12 17:23:21 +02:00
parent f1f1c4c980
commit 71c6eb2bb5
5 changed files with 182 additions and 112 deletions

View File

@@ -113,6 +113,8 @@ class ConfigurationClassParser {
private final ComponentScanAnnotationParser componentScanParser;
private final ConditionEvaluator conditionEvaluator;
private final Map<ConfigurationClass, ConfigurationClass> configurationClasses =
new LinkedHashMap<ConfigurationClass, ConfigurationClass>();
@@ -125,8 +127,6 @@ class ConfigurationClassParser {
private final List<DeferredImportSelectorHolder> deferredImportSelectors = new LinkedList<DeferredImportSelectorHolder>();
private final ConditionEvaluator conditionEvaluator;
/**
* Create a new {@link ConfigurationClassParser} instance that will be used
@@ -488,6 +488,10 @@ class ConfigurationClassParser {
return this.configurationClasses.keySet();
}
public int getPropertySourceCount() {
return this.propertySources.size();
}
public List<PropertySource<?>> getPropertySources() {
List<PropertySource<?>> propertySources = new LinkedList<PropertySource<?>>();
for (Map.Entry<String, List<ResourcePropertySource>> entry : this.propertySources.entrySet()) {

View File

@@ -17,6 +17,7 @@
package org.springframework.context.annotation;
import java.beans.PropertyDescriptor;
import java.util.Arrays;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
@@ -269,7 +270,9 @@ public class ConfigurationClassPostProcessor implements BeanDefinitionRegistryPo
*/
public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {
Set<BeanDefinitionHolder> configCandidates = new LinkedHashSet<BeanDefinitionHolder>();
for (String beanName : registry.getBeanDefinitionNames()) {
String[] candidateNames = registry.getBeanDefinitionNames();
for (String beanName : candidateNames) {
BeanDefinition beanDef = registry.getBeanDefinition(beanName);
if (ConfigurationClassUtils.isFullConfigurationClass(beanDef) ||
ConfigurationClassUtils.isLiteConfigurationClass(beanDef)) {
@@ -302,32 +305,59 @@ public class ConfigurationClassPostProcessor implements BeanDefinitionRegistryPo
ConfigurationClassParser parser = new ConfigurationClassParser(
this.metadataReaderFactory, this.problemReporter, this.environment,
this.resourceLoader, this.componentScanBeanNameGenerator, registry);
parser.parse(configCandidates);
parser.validate();
// Handle any @PropertySource annotations
List<PropertySource<?>> parsedPropertySources = parser.getPropertySources();
if (!parsedPropertySources.isEmpty()) {
if (!(this.environment instanceof ConfigurableEnvironment)) {
logger.warn("Ignoring @PropertySource annotations. " +
"Reason: Environment must implement ConfigurableEnvironment");
}
else {
MutablePropertySources envPropertySources = ((ConfigurableEnvironment) this.environment).getPropertySources();
for (PropertySource<?> propertySource : parsedPropertySources) {
envPropertySources.addLast(propertySource);
Set<ConfigurationClass> alreadyParsed = new HashSet<ConfigurationClass>(configCandidates.size());
int propertySourceCount = 0;
do {
parser.parse(configCandidates);
parser.validate();
// Handle any @PropertySource annotations
if (parser.getPropertySourceCount() > propertySourceCount) {
List<PropertySource<?>> parsedPropertySources = parser.getPropertySources();
if (!parsedPropertySources.isEmpty()) {
if (!(this.environment instanceof ConfigurableEnvironment)) {
logger.warn("Ignoring @PropertySource annotations. " +
"Reason: Environment must implement ConfigurableEnvironment");
}
else {
MutablePropertySources envPropertySources = ((ConfigurableEnvironment) this.environment).getPropertySources();
for (PropertySource<?> propertySource : parsedPropertySources) {
envPropertySources.addLast(propertySource);
}
}
}
propertySourceCount = parser.getPropertySourceCount();
}
Set<ConfigurationClass> configClasses = new LinkedHashSet<ConfigurationClass>(parser.getConfigurationClasses());
configClasses.removeAll(alreadyParsed);
// Read the model and create bean definitions based on its content
if (this.reader == null) {
this.reader = new ConfigurationClassBeanDefinitionReader(registry, this.sourceExtractor,
this.problemReporter, this.metadataReaderFactory, this.resourceLoader, this.environment,
this.importBeanNameGenerator);
}
this.reader.loadBeanDefinitions(configClasses);
alreadyParsed.addAll(configClasses);
configCandidates.clear();
if (registry.getBeanDefinitionCount() > candidateNames.length) {
String[] newCandidateNames = registry.getBeanDefinitionNames();
Set<String> oldCandidateNames = new HashSet<String>(Arrays.asList(candidateNames));
for (String candidateName : newCandidateNames) {
if (!oldCandidateNames.contains(candidateName)) {
BeanDefinition beanDef = registry.getBeanDefinition(candidateName);
if (ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory)) {
configCandidates.add(new BeanDefinitionHolder(beanDef, candidateName));
}
}
}
candidateNames = newCandidateNames;
}
}
// Read the model and create bean definitions based on its content
if (this.reader == null) {
this.reader = new ConfigurationClassBeanDefinitionReader(registry, this.sourceExtractor,
this.problemReporter, this.metadataReaderFactory, this.resourceLoader, this.environment,
this.importBeanNameGenerator);
}
this.reader.loadBeanDefinitions(parser.getConfigurationClasses());
while (!configCandidates.isEmpty());
// Register the ImportRegistry as a bean in order to support ImportAware @Configuration classes
if (singletonRegistry != null) {