@@ -139,7 +139,7 @@ public int compare(DeferredImportSelectorHolder o1, DeferredImportSelectorHolder
139139
140140 private final List <String > propertySourceNames = new ArrayList <>();
141141
142- private ImportStack importStack = new ImportStack ();
142+ private final ImportStack importStack = new ImportStack ();
143143
144144 private List <DeferredImportSelectorHolder > deferredImportSelectors ;
145145
@@ -182,7 +182,7 @@ else if (bd instanceof AbstractBeanDefinition && ((AbstractBeanDefinition) bd).h
182182 catch (BeanDefinitionStoreException ex ) {
183183 throw ex ;
184184 }
185- catch (Exception ex ) {
185+ catch (Throwable ex ) {
186186 throw new BeanDefinitionStoreException (
187187 "Failed to parse configuration class [" + bd .getBeanClassName () + "]" , ex );
188188 }
@@ -276,16 +276,7 @@ protected final SourceClass doProcessConfigurationClass(ConfigurationClass confi
276276 // Check the set of scanned definitions for any further config classes and parse recursively if necessary
277277 for (BeanDefinitionHolder holder : scannedBeanDefinitions ) {
278278 if (ConfigurationClassUtils .checkConfigurationClassCandidate (holder .getBeanDefinition (), this .metadataReaderFactory )) {
279- // Provide isolated circular import detection for scanned classes,
280- // since the initial registration did not come explicitly.
281- ImportStack previousStack = this .importStack ;
282- this .importStack = new ImportStack ();
283- try {
284- parse (holder .getBeanDefinition ().getBeanClassName (), holder .getBeanName ());
285- }
286- finally {
287- this .importStack = previousStack ;
288- }
279+ parse (holder .getBeanDefinition ().getBeanClassName (), holder .getBeanName ());
289280 }
290281 }
291282 }
@@ -493,7 +484,7 @@ private void processDeferredImportSelectors() {
493484 catch (BeanDefinitionStoreException ex ) {
494485 throw ex ;
495486 }
496- catch (Exception ex ) {
487+ catch (Throwable ex ) {
497488 throw new BeanDefinitionStoreException ("Failed to process import candidates for configuration class [" +
498489 configClass .getMetadata ().getClassName () + "]" , ex );
499490 }
@@ -507,7 +498,7 @@ private void processImports(ConfigurationClass configClass, SourceClass currentS
507498 return ;
508499 }
509500
510- if (checkForCircularImports && this . importStack . contains (configClass )) {
501+ if (checkForCircularImports && isChainedImportOnStack (configClass )) {
511502 this .problemReporter .error (new CircularImportProblem (configClass , this .importStack ));
512503 }
513504 else {
@@ -550,7 +541,7 @@ else if (candidate.isAssignable(ImportBeanDefinitionRegistrar.class)) {
550541 catch (BeanDefinitionStoreException ex ) {
551542 throw ex ;
552543 }
553- catch (Exception ex ) {
544+ catch (Throwable ex ) {
554545 throw new BeanDefinitionStoreException ("Failed to process import candidates for configuration class [" +
555546 configClass .getMetadata ().getClassName () + "]" , ex );
556547 }
@@ -560,6 +551,20 @@ else if (candidate.isAssignable(ImportBeanDefinitionRegistrar.class)) {
560551 }
561552 }
562553
554+ private boolean isChainedImportOnStack (ConfigurationClass configClass ) {
555+ if (this .importStack .contains (configClass )) {
556+ String configClassName = configClass .getMetadata ().getClassName ();
557+ AnnotationMetadata importingClass = this .importStack .getImportingClassFor (configClassName );
558+ while (importingClass != null ) {
559+ if (configClassName .equals (importingClass .getClassName ())) {
560+ return true ;
561+ }
562+ importingClass = this .importStack .getImportingClassFor (importingClass .getClassName ());
563+ }
564+ }
565+ return false ;
566+ }
567+
563568 /**
564569 * Invoke {@link ResourceLoaderAware}, {@link BeanClassLoaderAware} and
565570 * {@link BeanFactoryAware} contracts if implemented by the given {@code bean}.
0 commit comments