1
1
/*
2
- * Copyright 2002-2023 the original author or authors.
2
+ * Copyright 2002-2025 the original author or authors.
3
3
*
4
4
* Licensed under the Apache License, Version 2.0 (the "License");
5
5
* you may not use this file except in compliance with the License.
81
81
* any number of ConfigurationClass objects because one Configuration class may import
82
82
* another using the {@link Import} annotation).
83
83
*
84
- * <p>This class helps separate the concern of parsing the structure of a Configuration
85
- * class from the concern of registering BeanDefinition objects based on the content of
86
- * that model (with the exception of {@code @ComponentScan} annotations which need to be
87
- * registered immediately).
84
+ * <p>This class helps separate the concern of parsing the structure of a Configuration class
85
+ * from the concern of registering BeanDefinition objects based on the content of that model
86
+ * (except {@code @ComponentScan} annotations which need to be registered immediately).
88
87
*
89
88
* <p>This ASM-based implementation avoids reflection and eager class loading in order to
90
89
* interoperate effectively with lazy class loading in a Spring ApplicationContext.
@@ -161,14 +160,22 @@ public void parse(Set<BeanDefinitionHolder> configCandidates) {
161
160
for (BeanDefinitionHolder holder : configCandidates ) {
162
161
BeanDefinition bd = holder .getBeanDefinition ();
163
162
try {
163
+ ConfigurationClass configClass ;
164
164
if (bd instanceof AnnotatedBeanDefinition annotatedBeanDef ) {
165
- parse (annotatedBeanDef .getMetadata (), holder .getBeanName ());
165
+ configClass = parse (annotatedBeanDef .getMetadata (), holder .getBeanName ());
166
166
}
167
167
else if (bd instanceof AbstractBeanDefinition abstractBeanDef && abstractBeanDef .hasBeanClass ()) {
168
- parse (abstractBeanDef .getBeanClass (), holder .getBeanName ());
168
+ configClass = parse (abstractBeanDef .getBeanClass (), holder .getBeanName ());
169
169
}
170
170
else {
171
- parse (bd .getBeanClassName (), holder .getBeanName ());
171
+ configClass = parse (bd .getBeanClassName (), holder .getBeanName ());
172
+ }
173
+
174
+ // Downgrade to lite (no enhancement) in case of no instance-level @Bean methods.
175
+ if (!configClass .hasNonStaticBeanMethods () && ConfigurationClassUtils .CONFIGURATION_CLASS_FULL .equals (
176
+ bd .getAttribute (ConfigurationClassUtils .CONFIGURATION_CLASS_ATTRIBUTE ))) {
177
+ bd .setAttribute (ConfigurationClassUtils .CONFIGURATION_CLASS_ATTRIBUTE ,
178
+ ConfigurationClassUtils .CONFIGURATION_CLASS_LITE );
172
179
}
173
180
}
174
181
catch (BeanDefinitionStoreException ex ) {
@@ -183,31 +190,37 @@ else if (bd instanceof AbstractBeanDefinition abstractBeanDef && abstractBeanDef
183
190
this .deferredImportSelectorHandler .process ();
184
191
}
185
192
186
- protected final void parse (@ Nullable String className , String beanName ) throws IOException {
187
- Assert . notNull ( className , "No bean class name for configuration class bean definition" );
188
- MetadataReader reader = this . metadataReaderFactory . getMetadataReader ( className );
189
- processConfigurationClass ( new ConfigurationClass ( reader , beanName ), DEFAULT_EXCLUSION_FILTER ) ;
193
+ final ConfigurationClass parse (AnnotationMetadata metadata , String beanName ) {
194
+ ConfigurationClass configClass = new ConfigurationClass ( metadata , beanName );
195
+ processConfigurationClass ( configClass , DEFAULT_EXCLUSION_FILTER );
196
+ return configClass ;
190
197
}
191
198
192
- protected final void parse (Class <?> clazz , String beanName ) throws IOException {
193
- processConfigurationClass (new ConfigurationClass (clazz , beanName ), DEFAULT_EXCLUSION_FILTER );
199
+ final ConfigurationClass parse (Class <?> clazz , String beanName ) {
200
+ ConfigurationClass configClass = new ConfigurationClass (clazz , beanName );
201
+ processConfigurationClass (configClass , DEFAULT_EXCLUSION_FILTER );
202
+ return configClass ;
194
203
}
195
204
196
- protected final void parse (AnnotationMetadata metadata , String beanName ) throws IOException {
197
- processConfigurationClass (new ConfigurationClass (metadata , beanName ), DEFAULT_EXCLUSION_FILTER );
205
+ final ConfigurationClass parse (@ Nullable String className , String beanName ) throws IOException {
206
+ Assert .notNull (className , "No bean class name for configuration class bean definition" );
207
+ MetadataReader reader = this .metadataReaderFactory .getMetadataReader (className );
208
+ ConfigurationClass configClass = new ConfigurationClass (reader , beanName );
209
+ processConfigurationClass (configClass , DEFAULT_EXCLUSION_FILTER );
210
+ return configClass ;
198
211
}
199
212
200
213
/**
201
214
* Validate each {@link ConfigurationClass} object.
202
215
* @see ConfigurationClass#validate
203
216
*/
204
- public void validate () {
217
+ void validate () {
205
218
for (ConfigurationClass configClass : this .configurationClasses .keySet ()) {
206
219
configClass .validate (this .problemReporter );
207
220
}
208
221
}
209
222
210
- public Set <ConfigurationClass > getConfigurationClasses () {
223
+ Set <ConfigurationClass > getConfigurationClasses () {
211
224
return this .configurationClasses .keySet ();
212
225
}
213
226
@@ -216,7 +229,7 @@ List<PropertySourceDescriptor> getPropertySourceDescriptors() {
216
229
Collections .emptyList ());
217
230
}
218
231
219
- protected void processConfigurationClass (ConfigurationClass configClass , Predicate <String > filter ) throws IOException {
232
+ protected void processConfigurationClass (ConfigurationClass configClass , Predicate <String > filter ) {
220
233
if (this .conditionEvaluator .shouldSkip (configClass .getMetadata (), ConfigurationPhase .PARSE_CONFIGURATION )) {
221
234
return ;
222
235
}
@@ -448,7 +461,7 @@ private Set<MethodMetadata> retrieveBeanMethodMetadata(SourceClass sourceClass)
448
461
449
462
450
463
/**
451
- * Returns {@code @Import} class , considering all meta-annotations.
464
+ * Returns {@code @Import} classes , considering all meta-annotations.
452
465
*/
453
466
private Set <SourceClass > getImports (SourceClass sourceClass ) throws IOException {
454
467
Set <SourceClass > imports = new LinkedHashSet <>();
@@ -636,7 +649,7 @@ private static class ImportStack extends ArrayDeque<ConfigurationClass> implemen
636
649
637
650
private final MultiValueMap <String , AnnotationMetadata > imports = new LinkedMultiValueMap <>();
638
651
639
- public void registerImport (AnnotationMetadata importingClass , String importedClass ) {
652
+ void registerImport (AnnotationMetadata importingClass , String importedClass ) {
640
653
this .imports .add (importedClass , importingClass );
641
654
}
642
655
@@ -691,7 +704,7 @@ private class DeferredImportSelectorHandler {
691
704
* @param configClass the source configuration class
692
705
* @param importSelector the selector to handle
693
706
*/
694
- public void handle (ConfigurationClass configClass , DeferredImportSelector importSelector ) {
707
+ void handle (ConfigurationClass configClass , DeferredImportSelector importSelector ) {
695
708
DeferredImportSelectorHolder holder = new DeferredImportSelectorHolder (configClass , importSelector );
696
709
if (this .deferredImportSelectors == null ) {
697
710
DeferredImportSelectorGroupingHandler handler = new DeferredImportSelectorGroupingHandler ();
@@ -703,7 +716,7 @@ public void handle(ConfigurationClass configClass, DeferredImportSelector import
703
716
}
704
717
}
705
718
706
- public void process () {
719
+ void process () {
707
720
List <DeferredImportSelectorHolder > deferredImports = this .deferredImportSelectors ;
708
721
this .deferredImportSelectors = null ;
709
722
try {
@@ -727,7 +740,7 @@ private class DeferredImportSelectorGroupingHandler {
727
740
728
741
private final Map <AnnotationMetadata , ConfigurationClass > configurationClasses = new HashMap <>();
729
742
730
- public void register (DeferredImportSelectorHolder deferredImport ) {
743
+ void register (DeferredImportSelectorHolder deferredImport ) {
731
744
Class <? extends Group > group = deferredImport .getImportSelector ().getImportGroup ();
732
745
DeferredImportSelectorGrouping grouping = this .groupings .computeIfAbsent (
733
746
(group != null ? group : deferredImport ),
@@ -737,7 +750,7 @@ public void register(DeferredImportSelectorHolder deferredImport) {
737
750
deferredImport .getConfigurationClass ());
738
751
}
739
752
740
- public void processGroupImports () {
753
+ void processGroupImports () {
741
754
for (DeferredImportSelectorGrouping grouping : this .groupings .values ()) {
742
755
Predicate <String > exclusionFilter = grouping .getCandidateFilter ();
743
756
grouping .getImports ().forEach (entry -> {
@@ -775,16 +788,16 @@ private static class DeferredImportSelectorHolder {
775
788
776
789
private final DeferredImportSelector importSelector ;
777
790
778
- public DeferredImportSelectorHolder (ConfigurationClass configClass , DeferredImportSelector selector ) {
791
+ DeferredImportSelectorHolder (ConfigurationClass configClass , DeferredImportSelector selector ) {
779
792
this .configurationClass = configClass ;
780
793
this .importSelector = selector ;
781
794
}
782
795
783
- public ConfigurationClass getConfigurationClass () {
796
+ ConfigurationClass getConfigurationClass () {
784
797
return this .configurationClass ;
785
798
}
786
799
787
- public DeferredImportSelector getImportSelector () {
800
+ DeferredImportSelector getImportSelector () {
788
801
return this .importSelector ;
789
802
}
790
803
}
@@ -800,23 +813,23 @@ private static class DeferredImportSelectorGrouping {
800
813
this .group = group ;
801
814
}
802
815
803
- public void add (DeferredImportSelectorHolder deferredImport ) {
816
+ void add (DeferredImportSelectorHolder deferredImport ) {
804
817
this .deferredImports .add (deferredImport );
805
818
}
806
819
807
820
/**
808
821
* Return the imports defined by the group.
809
822
* @return each import with its associated configuration class
810
823
*/
811
- public Iterable <Group .Entry > getImports () {
824
+ Iterable <Group .Entry > getImports () {
812
825
for (DeferredImportSelectorHolder deferredImport : this .deferredImports ) {
813
826
this .group .process (deferredImport .getConfigurationClass ().getMetadata (),
814
827
deferredImport .getImportSelector ());
815
828
}
816
829
return this .group .selectImports ();
817
830
}
818
831
819
- public Predicate <String > getCandidateFilter () {
832
+ Predicate <String > getCandidateFilter () {
820
833
Predicate <String > mergedFilter = DEFAULT_EXCLUSION_FILTER ;
821
834
for (DeferredImportSelectorHolder deferredImport : this .deferredImports ) {
822
835
Predicate <String > selectorFilter = deferredImport .getImportSelector ().getExclusionFilter ();
0 commit comments