Skip to content

Commit 1a8c6fa

Browse files
committed
Deferred import processing reliably detects late registration attempts
Issue: SPR-12838
1 parent 7f845f7 commit 1a8c6fa

File tree

1 file changed

+14
-9
lines changed

1 file changed

+14
-9
lines changed

spring-context/src/main/java/org/springframework/context/annotation/ConfigurationClassParser.java

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ public int compare(DeferredImportSelectorHolder o1, DeferredImportSelectorHolder
133133

134134
private final ImportStack importStack = new ImportStack();
135135

136-
private final List<DeferredImportSelectorHolder> deferredImportSelectors = new LinkedList<DeferredImportSelectorHolder>();
136+
private List<DeferredImportSelectorHolder> deferredImportSelectors;
137137

138138

139139
/**
@@ -156,6 +156,8 @@ public ConfigurationClassParser(MetadataReaderFactory metadataReaderFactory,
156156

157157

158158
public void parse(Set<BeanDefinitionHolder> configCandidates) {
159+
this.deferredImportSelectors = new LinkedList<DeferredImportSelectorHolder>();
160+
159161
for (BeanDefinitionHolder holder : configCandidates) {
160162
BeanDefinition bd = holder.getBeanDefinition();
161163
try {
@@ -177,6 +179,7 @@ else if (bd instanceof AbstractBeanDefinition && ((AbstractBeanDefinition) bd).h
177179
"Failed to parse configuration class [" + bd.getBeanClassName() + "]", ex);
178180
}
179181
}
182+
180183
processDeferredImportSelectors();
181184
}
182185

@@ -269,7 +272,7 @@ protected final SourceClass doProcessConfigurationClass(ConfigurationClass confi
269272
}
270273

271274
// Process any @Import annotations
272-
processImports(configClass, sourceClass, getImports(sourceClass), true, false);
275+
processImports(configClass, sourceClass, getImports(sourceClass), true);
273276

274277
// Process any @ImportResource annotations
275278
if (sourceClass.getMetadata().isAnnotated(ImportResource.class.getName())) {
@@ -427,12 +430,15 @@ private void collectImports(SourceClass sourceClass, Set<SourceClass> imports, S
427430
}
428431

429432
private void processDeferredImportSelectors() {
430-
Collections.sort(this.deferredImportSelectors, DEFERRED_IMPORT_COMPARATOR);
431-
for (DeferredImportSelectorHolder deferredImport : this.deferredImportSelectors) {
433+
List<DeferredImportSelectorHolder> deferredImports = this.deferredImportSelectors;
434+
this.deferredImportSelectors = null;
435+
Collections.sort(deferredImports, DEFERRED_IMPORT_COMPARATOR);
436+
437+
for (DeferredImportSelectorHolder deferredImport : deferredImports) {
432438
ConfigurationClass configClass = deferredImport.getConfigurationClass();
433439
try {
434440
String[] imports = deferredImport.getImportSelector().selectImports(configClass.getMetadata());
435-
processImports(configClass, asSourceClass(configClass), asSourceClasses(imports), false, true);
441+
processImports(configClass, asSourceClass(configClass), asSourceClasses(imports), false);
436442
}
437443
catch (BeanDefinitionStoreException ex) {
438444
throw ex;
@@ -442,11 +448,10 @@ private void processDeferredImportSelectors() {
442448
configClass.getMetadata().getClassName() + "]", ex);
443449
}
444450
}
445-
this.deferredImportSelectors.clear();
446451
}
447452

448453
private void processImports(ConfigurationClass configClass, SourceClass currentSourceClass,
449-
Collection<SourceClass> importCandidates, boolean checkForCircularImports, boolean deferred) throws IOException {
454+
Collection<SourceClass> importCandidates, boolean checkForCircularImports) throws IOException {
450455

451456
if (importCandidates.isEmpty()) {
452457
return;
@@ -464,14 +469,14 @@ private void processImports(ConfigurationClass configClass, SourceClass currentS
464469
Class<?> candidateClass = candidate.loadClass();
465470
ImportSelector selector = BeanUtils.instantiateClass(candidateClass, ImportSelector.class);
466471
invokeAwareMethods(selector);
467-
if (!deferred && selector instanceof DeferredImportSelector) {
472+
if (this.deferredImportSelectors != null && selector instanceof DeferredImportSelector) {
468473
this.deferredImportSelectors.add(
469474
new DeferredImportSelectorHolder(configClass, (DeferredImportSelector) selector));
470475
}
471476
else {
472477
String[] importClassNames = selector.selectImports(currentSourceClass.getMetadata());
473478
Collection<SourceClass> importSourceClasses = asSourceClasses(importClassNames);
474-
processImports(configClass, currentSourceClass, importSourceClasses, false, false);
479+
processImports(configClass, currentSourceClass, importSourceClasses, false);
475480
}
476481
}
477482
else if (candidate.isAssignable(ImportBeanDefinitionRegistrar.class)) {

0 commit comments

Comments
 (0)