30
30
import java .util .Iterator ;
31
31
import java .util .LinkedHashMap ;
32
32
import java .util .LinkedHashSet ;
33
- import java .util .LinkedList ;
34
33
import java .util .List ;
35
34
import java .util .Map ;
36
35
import java .util .Set ;
@@ -138,8 +137,7 @@ class ConfigurationClassParser {
138
137
139
138
private final ImportStack importStack = new ImportStack ();
140
139
141
- @ Nullable
142
- private List <DeferredImportSelectorHolder > deferredImportSelectors ;
140
+ private final DeferredImportSelectorHandler deferredImportSelectorHandler = new DeferredImportSelectorHandler ();
143
141
144
142
145
143
/**
@@ -162,8 +160,6 @@ public ConfigurationClassParser(MetadataReaderFactory metadataReaderFactory,
162
160
163
161
164
162
public void parse (Set <BeanDefinitionHolder > configCandidates ) {
165
- this .deferredImportSelectors = new LinkedList <>();
166
-
167
163
for (BeanDefinitionHolder holder : configCandidates ) {
168
164
BeanDefinition bd = holder .getBeanDefinition ();
169
165
try {
@@ -186,7 +182,7 @@ else if (bd instanceof AbstractBeanDefinition && ((AbstractBeanDefinition) bd).h
186
182
}
187
183
}
188
184
189
- processDeferredImportSelectors ();
185
+ this . deferredImportSelectorHandler . process ();
190
186
}
191
187
192
188
protected final void parse (@ Nullable String className , String beanName ) throws IOException {
@@ -543,53 +539,7 @@ private void collectImports(SourceClass sourceClass, Set<SourceClass> imports, S
543
539
}
544
540
}
545
541
546
- private void processDeferredImportSelectors () {
547
- List <DeferredImportSelectorHolder > deferredImports = this .deferredImportSelectors ;
548
- this .deferredImportSelectors = null ;
549
- if (deferredImports == null ) {
550
- return ;
551
- }
552
-
553
- deferredImports .sort (DEFERRED_IMPORT_COMPARATOR );
554
- Map <Object , DeferredImportSelectorGrouping > groupings = new LinkedHashMap <>();
555
- Map <AnnotationMetadata , ConfigurationClass > configurationClasses = new HashMap <>();
556
- for (DeferredImportSelectorHolder deferredImport : deferredImports ) {
557
- Class <? extends Group > group = deferredImport .getImportSelector ().getImportGroup ();
558
- DeferredImportSelectorGrouping grouping = groupings .computeIfAbsent (
559
- (group != null ? group : deferredImport ),
560
- key -> new DeferredImportSelectorGrouping (createGroup (group )));
561
- grouping .add (deferredImport );
562
- configurationClasses .put (deferredImport .getConfigurationClass ().getMetadata (),
563
- deferredImport .getConfigurationClass ());
564
- }
565
- for (DeferredImportSelectorGrouping grouping : groupings .values ()) {
566
- grouping .getImports ().forEach (entry -> {
567
- ConfigurationClass configurationClass = configurationClasses .get (entry .getMetadata ());
568
- try {
569
- processImports (configurationClass , asSourceClass (configurationClass ),
570
- asSourceClasses (entry .getImportClassName ()), false );
571
- }
572
- catch (BeanDefinitionStoreException ex ) {
573
- throw ex ;
574
- }
575
- catch (Throwable ex ) {
576
- throw new BeanDefinitionStoreException (
577
- "Failed to process import candidates for configuration class [" +
578
- configurationClass .getMetadata ().getClassName () + "]" , ex );
579
- }
580
- });
581
- }
582
- }
583
542
584
- private Group createGroup (@ Nullable Class <? extends Group > type ) {
585
- Class <? extends Group > effectiveType = (type != null ? type : DefaultDeferredImportSelectorGroup .class );
586
- Group group = BeanUtils .instantiateClass (effectiveType );
587
- ParserStrategyUtils .invokeAwareMethods (group ,
588
- ConfigurationClassParser .this .environment ,
589
- ConfigurationClassParser .this .resourceLoader ,
590
- ConfigurationClassParser .this .registry );
591
- return group ;
592
- }
593
543
594
544
private void processImports (ConfigurationClass configClass , SourceClass currentSourceClass ,
595
545
Collection <SourceClass > importCandidates , boolean checkForCircularImports ) {
@@ -611,9 +561,9 @@ private void processImports(ConfigurationClass configClass, SourceClass currentS
611
561
ImportSelector selector = BeanUtils .instantiateClass (candidateClass , ImportSelector .class );
612
562
ParserStrategyUtils .invokeAwareMethods (
613
563
selector , this .environment , this .resourceLoader , this .registry );
614
- if (this . deferredImportSelectors != null && selector instanceof DeferredImportSelector ) {
615
- this .deferredImportSelectors . add (
616
- new DeferredImportSelectorHolder ( configClass , (DeferredImportSelector ) selector ) );
564
+ if (selector instanceof DeferredImportSelector ) {
565
+ this .deferredImportSelectorHandler . handle (
566
+ configClass , (DeferredImportSelector ) selector );
617
567
}
618
568
else {
619
569
String [] importClassNames = selector .selectImports (currentSourceClass .getMetadata ());
@@ -787,6 +737,103 @@ public String toString() {
787
737
}
788
738
789
739
740
+ private class DeferredImportSelectorHandler {
741
+
742
+ @ Nullable
743
+ private List <DeferredImportSelectorHolder > deferredImportSelectors = new ArrayList <>();
744
+
745
+ /**
746
+ * Handle the specified {@link DeferredImportSelector}. If deferred import
747
+ * selectors are being collected, this registers this instance to the list. If
748
+ * they are being processed, the {@link DeferredImportSelector} is also processed
749
+ * immediately according to its {@link DeferredImportSelector.Group}.
750
+ * @param configClass the source configuration class
751
+ * @param importSelector the selector to handle
752
+ */
753
+ public void handle (ConfigurationClass configClass , DeferredImportSelector importSelector ) {
754
+ DeferredImportSelectorHolder holder = new DeferredImportSelectorHolder (
755
+ configClass , importSelector );
756
+ if (this .deferredImportSelectors == null ) {
757
+ DeferredImportSelectorGroupingHandler handler = new DeferredImportSelectorGroupingHandler ();
758
+ handler .register (holder );
759
+ handler .processGroupImports ();
760
+ }
761
+ else {
762
+ this .deferredImportSelectors .add (holder );
763
+ }
764
+ }
765
+
766
+ public void process () {
767
+ List <DeferredImportSelectorHolder > deferredImports = this .deferredImportSelectors ;
768
+ this .deferredImportSelectors = null ;
769
+ try {
770
+ if (deferredImports != null ) {
771
+ DeferredImportSelectorGroupingHandler handler = new DeferredImportSelectorGroupingHandler ();
772
+ deferredImports .sort (DEFERRED_IMPORT_COMPARATOR );
773
+ deferredImports .forEach (handler ::register );
774
+ handler .processGroupImports ();
775
+ }
776
+ }
777
+ finally {
778
+ this .deferredImportSelectors = new ArrayList <>();
779
+ }
780
+ }
781
+
782
+ }
783
+
784
+
785
+ private class DeferredImportSelectorGroupingHandler {
786
+
787
+ private final Map <Object , DeferredImportSelectorGrouping > groupings = new LinkedHashMap <>();
788
+
789
+ private final Map <AnnotationMetadata , ConfigurationClass > configurationClasses = new HashMap <>();
790
+
791
+ public void register (DeferredImportSelectorHolder deferredImport ) {
792
+ Class <? extends Group > group = deferredImport .getImportSelector ()
793
+ .getImportGroup ();
794
+ DeferredImportSelectorGrouping grouping = this .groupings .computeIfAbsent (
795
+ (group != null ? group : deferredImport ),
796
+ key -> new DeferredImportSelectorGrouping (createGroup (group )));
797
+ grouping .add (deferredImport );
798
+ this .configurationClasses .put (deferredImport .getConfigurationClass ().getMetadata (),
799
+ deferredImport .getConfigurationClass ());
800
+ }
801
+
802
+ public void processGroupImports () {
803
+ for (DeferredImportSelectorGrouping grouping : this .groupings .values ()) {
804
+ grouping .getImports ().forEach (entry -> {
805
+ ConfigurationClass configurationClass = this .configurationClasses .get (
806
+ entry .getMetadata ());
807
+ try {
808
+ processImports (configurationClass , asSourceClass (configurationClass ),
809
+ asSourceClasses (entry .getImportClassName ()), false );
810
+ }
811
+ catch (BeanDefinitionStoreException ex ) {
812
+ throw ex ;
813
+ }
814
+ catch (Throwable ex ) {
815
+ throw new BeanDefinitionStoreException (
816
+ "Failed to process import candidates for configuration class [" +
817
+ configurationClass .getMetadata ().getClassName () + "]" , ex );
818
+ }
819
+ });
820
+ }
821
+ }
822
+
823
+ private Group createGroup (@ Nullable Class <? extends Group > type ) {
824
+ Class <? extends Group > effectiveType = (type != null ? type
825
+ : DefaultDeferredImportSelectorGroup .class );
826
+ Group group = BeanUtils .instantiateClass (effectiveType );
827
+ ParserStrategyUtils .invokeAwareMethods (group ,
828
+ ConfigurationClassParser .this .environment ,
829
+ ConfigurationClassParser .this .resourceLoader ,
830
+ ConfigurationClassParser .this .registry );
831
+ return group ;
832
+ }
833
+
834
+ }
835
+
836
+
790
837
private static class DeferredImportSelectorHolder {
791
838
792
839
private final ConfigurationClass configurationClass ;
0 commit comments