|
|
|
@ -232,7 +232,7 @@ class ConfigurationClassParser { |
|
|
|
// Explicit bean definition found, probably replacing an import.
|
|
|
|
// Explicit bean definition found, probably replacing an import.
|
|
|
|
// Let's remove the old one and go with the new one.
|
|
|
|
// Let's remove the old one and go with the new one.
|
|
|
|
this.configurationClasses.remove(configClass); |
|
|
|
this.configurationClasses.remove(configClass); |
|
|
|
for (Iterator<ConfigurationClass> it = this.knownSuperclasses.values().iterator(); it.hasNext(); ) { |
|
|
|
for (Iterator<ConfigurationClass> it = this.knownSuperclasses.values().iterator(); it.hasNext();) { |
|
|
|
if (configClass.equals(it.next())) { |
|
|
|
if (configClass.equals(it.next())) { |
|
|
|
it.remove(); |
|
|
|
it.remove(); |
|
|
|
} |
|
|
|
} |
|
|
|
@ -258,13 +258,16 @@ class ConfigurationClassParser { |
|
|
|
* @param sourceClass a source class
|
|
|
|
* @param sourceClass a source class
|
|
|
|
* @return the superclass, or {@code null} if none found or previously processed |
|
|
|
* @return the superclass, or {@code null} if none found or previously processed |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
protected final SourceClass doProcessConfigurationClass(ConfigurationClass configClass, SourceClass sourceClass) throws IOException { |
|
|
|
protected final SourceClass doProcessConfigurationClass(ConfigurationClass configClass, SourceClass sourceClass) |
|
|
|
|
|
|
|
throws IOException { |
|
|
|
|
|
|
|
|
|
|
|
// Recursively process any member (nested) classes first
|
|
|
|
// Recursively process any member (nested) classes first
|
|
|
|
processMemberClasses(configClass, sourceClass); |
|
|
|
processMemberClasses(configClass, sourceClass); |
|
|
|
|
|
|
|
|
|
|
|
// Process any @PropertySource annotations
|
|
|
|
// Process any @PropertySource annotations
|
|
|
|
for (AnnotationAttributes propertySource : AnnotationConfigUtils.attributesForRepeatable( |
|
|
|
for (AnnotationAttributes propertySource : AnnotationConfigUtils.attributesForRepeatable( |
|
|
|
sourceClass.getMetadata(), PropertySources.class, org.springframework.context.annotation.PropertySource.class)) { |
|
|
|
sourceClass.getMetadata(), PropertySources.class, |
|
|
|
|
|
|
|
org.springframework.context.annotation.PropertySource.class)) { |
|
|
|
if (this.environment instanceof ConfigurableEnvironment) { |
|
|
|
if (this.environment instanceof ConfigurableEnvironment) { |
|
|
|
processPropertySource(propertySource); |
|
|
|
processPropertySource(propertySource); |
|
|
|
} |
|
|
|
} |
|
|
|
@ -277,14 +280,16 @@ class ConfigurationClassParser { |
|
|
|
// Process any @ComponentScan annotations
|
|
|
|
// Process any @ComponentScan annotations
|
|
|
|
Set<AnnotationAttributes> componentScans = AnnotationConfigUtils.attributesForRepeatable( |
|
|
|
Set<AnnotationAttributes> componentScans = AnnotationConfigUtils.attributesForRepeatable( |
|
|
|
sourceClass.getMetadata(), ComponentScans.class, ComponentScan.class); |
|
|
|
sourceClass.getMetadata(), ComponentScans.class, ComponentScan.class); |
|
|
|
if (!componentScans.isEmpty() && !this.conditionEvaluator.shouldSkip(sourceClass.getMetadata(), ConfigurationPhase.REGISTER_BEAN)) { |
|
|
|
if (!componentScans.isEmpty() && |
|
|
|
|
|
|
|
!this.conditionEvaluator.shouldSkip(sourceClass.getMetadata(), ConfigurationPhase.REGISTER_BEAN)) { |
|
|
|
for (AnnotationAttributes componentScan : componentScans) { |
|
|
|
for (AnnotationAttributes componentScan : componentScans) { |
|
|
|
// The config class is annotated with @ComponentScan -> perform the scan immediately
|
|
|
|
// The config class is annotated with @ComponentScan -> perform the scan immediately
|
|
|
|
Set<BeanDefinitionHolder> scannedBeanDefinitions = |
|
|
|
Set<BeanDefinitionHolder> scannedBeanDefinitions = |
|
|
|
this.componentScanParser.parse(componentScan, sourceClass.getMetadata().getClassName()); |
|
|
|
this.componentScanParser.parse(componentScan, sourceClass.getMetadata().getClassName()); |
|
|
|
// Check the set of scanned definitions for any further config classes and parse recursively if necessary
|
|
|
|
// Check the set of scanned definitions for any further config classes and parse recursively if needed
|
|
|
|
for (BeanDefinitionHolder holder : scannedBeanDefinitions) { |
|
|
|
for (BeanDefinitionHolder holder : scannedBeanDefinitions) { |
|
|
|
if (ConfigurationClassUtils.checkConfigurationClassCandidate(holder.getBeanDefinition(), this.metadataReaderFactory)) { |
|
|
|
if (ConfigurationClassUtils.checkConfigurationClassCandidate( |
|
|
|
|
|
|
|
holder.getBeanDefinition(), this.metadataReaderFactory)) { |
|
|
|
parse(holder.getBeanDefinition().getBeanClassName(), holder.getBeanName()); |
|
|
|
parse(holder.getBeanDefinition().getBeanClassName(), holder.getBeanName()); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
@ -514,7 +519,9 @@ class ConfigurationClassParser { |
|
|
|
* @param visited used to track visited classes to prevent infinite recursion |
|
|
|
* @param visited used to track visited classes to prevent infinite recursion |
|
|
|
* @throws IOException if there is any problem reading metadata from the named class
|
|
|
|
* @throws IOException if there is any problem reading metadata from the named class
|
|
|
|
*/ |
|
|
|
*/ |
|
|
|
private void collectImports(SourceClass sourceClass, Set<SourceClass> imports, Set<SourceClass> visited) throws IOException { |
|
|
|
private void collectImports(SourceClass sourceClass, Set<SourceClass> imports, Set<SourceClass> visited) |
|
|
|
|
|
|
|
throws IOException { |
|
|
|
|
|
|
|
|
|
|
|
if (visited.add(sourceClass)) { |
|
|
|
if (visited.add(sourceClass)) { |
|
|
|
for (SourceClass annotation : sourceClass.getAnnotations()) { |
|
|
|
for (SourceClass annotation : sourceClass.getAnnotations()) { |
|
|
|
String annName = annotation.getMetadata().getClassName(); |
|
|
|
String annName = annotation.getMetadata().getClassName(); |
|
|
|
@ -541,7 +548,8 @@ class ConfigurationClassParser { |
|
|
|
throw ex; |
|
|
|
throw ex; |
|
|
|
} |
|
|
|
} |
|
|
|
catch (Throwable ex) { |
|
|
|
catch (Throwable ex) { |
|
|
|
throw new BeanDefinitionStoreException("Failed to process import candidates for configuration class [" + |
|
|
|
throw new BeanDefinitionStoreException( |
|
|
|
|
|
|
|
"Failed to process import candidates for configuration class [" + |
|
|
|
configClass.getMetadata().getClassName() + "]", ex); |
|
|
|
configClass.getMetadata().getClassName() + "]", ex); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
@ -600,7 +608,8 @@ class ConfigurationClassParser { |
|
|
|
throw ex; |
|
|
|
throw ex; |
|
|
|
} |
|
|
|
} |
|
|
|
catch (Throwable ex) { |
|
|
|
catch (Throwable ex) { |
|
|
|
throw new BeanDefinitionStoreException("Failed to process import candidates for configuration class [" + |
|
|
|
throw new BeanDefinitionStoreException( |
|
|
|
|
|
|
|
"Failed to process import candidates for configuration class [" + |
|
|
|
configClass.getMetadata().getClassName() + "]", ex); |
|
|
|
configClass.getMetadata().getClassName() + "]", ex); |
|
|
|
} |
|
|
|
} |
|
|
|
finally { |
|
|
|
finally { |
|
|
|
@ -739,9 +748,9 @@ class ConfigurationClassParser { |
|
|
|
|
|
|
|
|
|
|
|
private final DeferredImportSelector importSelector; |
|
|
|
private final DeferredImportSelector importSelector; |
|
|
|
|
|
|
|
|
|
|
|
public DeferredImportSelectorHolder(ConfigurationClass configurationClass, DeferredImportSelector importSelector) { |
|
|
|
public DeferredImportSelectorHolder(ConfigurationClass configClass, DeferredImportSelector selector) { |
|
|
|
this.configurationClass = configurationClass; |
|
|
|
this.configurationClass = configClass; |
|
|
|
this.importSelector = importSelector; |
|
|
|
this.importSelector = selector; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public ConfigurationClass getConfigurationClass() { |
|
|
|
public ConfigurationClass getConfigurationClass() { |
|
|
|
@ -881,8 +890,8 @@ class ConfigurationClassParser { |
|
|
|
return result; |
|
|
|
return result; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public Collection<SourceClass> getAnnotationAttributes(String annotationType, String attribute) throws IOException { |
|
|
|
public Collection<SourceClass> getAnnotationAttributes(String annType, String attribute) throws IOException { |
|
|
|
Map<String, Object> annotationAttributes = this.metadata.getAnnotationAttributes(annotationType, true); |
|
|
|
Map<String, Object> annotationAttributes = this.metadata.getAnnotationAttributes(annType, true); |
|
|
|
if (annotationAttributes == null || !annotationAttributes.containsKey(attribute)) { |
|
|
|
if (annotationAttributes == null || !annotationAttributes.containsKey(attribute)) { |
|
|
|
return Collections.emptySet(); |
|
|
|
return Collections.emptySet(); |
|
|
|
} |
|
|
|
} |
|
|
|
|