2323import java .util .Collections ;
2424import java .util .Comparator ;
2525import java .util .HashMap ;
26- import java .util .HashSet ;
2726import java .util .Iterator ;
28- import java .util .LinkedHashMap ;
2927import java .util .LinkedHashSet ;
3028import java .util .Map ;
31- import java .util .Map .Entry ;
3229import java .util .Set ;
3330import java .util .Stack ;
3431
7976 *
8077 * @author Chris Beams
8178 * @author Juergen Hoeller
82- * @author Rob Winch
8379 * @since 3.0
8480 * @see ConfigurationClassBeanDefinitionReader
8581 */
@@ -91,14 +87,6 @@ class ConfigurationClassParser {
9187
9288 private final ImportStack importStack = new ImportStack ();
9389
94- private final Set <String > knownSuperclasses = new LinkedHashSet <String >();
95-
96- private final Map <ConfigurationClass ,ConfigurationClass > configurationClasses =
97- new LinkedHashMap <ConfigurationClass ,ConfigurationClass >();
98-
99- private final Stack <PropertySource <?>> propertySources =
100- new Stack <PropertySource <?>>();
101-
10290 private final Environment environment ;
10391
10492 private final ResourceLoader resourceLoader ;
@@ -107,6 +95,12 @@ class ConfigurationClassParser {
10795
10896 private final ComponentScanAnnotationParser componentScanParser ;
10997
98+ private final Set <ConfigurationClass > configurationClasses = new LinkedHashSet <ConfigurationClass >();
99+
100+ private final Map <String , ConfigurationClass > knownSuperclasses = new HashMap <String , ConfigurationClass >();
101+
102+ private final Stack <PropertySource <?>> propertySources = new Stack <PropertySource <?>>();
103+
110104
111105 /**
112106 * Create a new {@link ConfigurationClassParser} instance that will be used
@@ -155,70 +149,28 @@ protected void processConfigurationClass(ConfigurationClass configClass) throws
155149 }
156150 }
157151
158- // recursively process the configuration class and its superclass hierarchy
159- do {
160- metadata = doProcessConfigurationClass (configClass , metadata );
161- }
162- while (metadata != null );
163-
164- if (getConfigurationClasses ().contains (configClass ) && configClass .getBeanName () != null ) {
152+ if (this .configurationClasses .contains (configClass ) && configClass .getBeanName () != null ) {
165153 // Explicit bean definition found, probably replacing an import.
166154 // Let's remove the old one and go with the new one.
167- ConfigurationClass originalConfigClass = removeConfigurationClass (configClass );
168-
169- mergeFromOriginalConfig (originalConfigClass ,configClass );
170- }
171-
172- addConfigurationClass (configClass );
173- }
174-
175-
176- /**
177- * Merges from the original {@link ConfigurationClass} to the new
178- * {@link ConfigurationClass}. This is necessary if parent classes have already been
179- * processed.
180- *
181- * @param originalConfigClass the original {@link ConfigurationClass} that may have
182- * additional metadata
183- * @param configClass the new {@link ConfigurationClass} that will have metadata added
184- * to it if necessary
185- */
186- private void mergeFromOriginalConfig (ConfigurationClass originalConfigClass ,
187- ConfigurationClass configClass ) {
188-
189- Set <String > beanMethodNames = new HashSet <String >();
190- for (BeanMethod beanMethod : configClass .getBeanMethods ()) {
191- beanMethodNames .add (createBeanMethodName (beanMethod ));
192- }
193-
194- for (BeanMethod originalBeanMethod : originalConfigClass .getBeanMethods ()) {
195- String originalBeanMethodName = createBeanMethodName (originalBeanMethod );
196- if (!beanMethodNames .contains (originalBeanMethodName )) {
197- configClass .addBeanMethod (new BeanMethod (originalBeanMethod .getMetadata (), configClass ));
155+ this .configurationClasses .remove (configClass );
156+ for (Iterator <ConfigurationClass > it = this .knownSuperclasses .values ().iterator (); it .hasNext ();) {
157+ if (configClass .equals (it .next ())) {
158+ it .remove ();
159+ }
198160 }
199161 }
200- for ( Entry < String , Class <? extends BeanDefinitionReader >> originalImportedEntry : originalConfigClass . getImportedResources (). entrySet ()) {
201- if (! configClass . getImportedResources (). containsKey ( originalImportedEntry . getKey ())) {
202- configClass . addImportedResource ( originalImportedEntry . getKey (), originalImportedEntry . getValue ());
203- }
162+
163+ // Recursively process the configuration class and its superclass hierarchy.
164+ do {
165+ metadata = doProcessConfigurationClass ( configClass , metadata );
204166 }
205- }
167+ while ( metadata != null );
206168
207- /**
208- * Converts a {@link BeanMethod} into the fully qualified name of the Method
209- *
210- * @param beanMethod
211- * @return fully qualified name of the {@link BeanMethod}
212- */
213- private String createBeanMethodName (BeanMethod beanMethod ) {
214- String hashDelim = "#" ;
215- String dClassName = beanMethod .getMetadata ().getDeclaringClassName ();
216- String methodName = beanMethod .getMetadata ().getMethodName ();
217- return dClassName + hashDelim + methodName ;
169+ this .configurationClasses .add (configClass );
218170 }
219171
220172 /**
221- * @return annotation metadata of superclass, null if none found or previously processed
173+ * @return annotation metadata of superclass, {@code null} if none found or previously processed
222174 */
223175 protected AnnotationMetadata doProcessConfigurationClass (
224176 ConfigurationClass configClass , AnnotationMetadata metadata ) throws IOException {
@@ -232,7 +184,7 @@ protected AnnotationMetadata doProcessConfigurationClass(
232184 processPropertySource (propertySource );
233185 }
234186
235- // process any @ComponentScan annotions
187+ // process any @ComponentScan annotations
236188 AnnotationAttributes componentScan = attributesFor (metadata , ComponentScan .class );
237189 if (componentScan != null ) {
238190 // the config class is annotated with @ComponentScan -> perform the scan immediately
@@ -248,7 +200,6 @@ protected AnnotationMetadata doProcessConfigurationClass(
248200 }
249201
250202 // process any @Import annotations
251-
252203 Set <Object > imports = new LinkedHashSet <Object >();
253204 Set <Object > visited = new LinkedHashSet <Object >();
254205 collectImports (metadata , imports , visited );
@@ -275,7 +226,8 @@ protected AnnotationMetadata doProcessConfigurationClass(
275226 // process superclass, if any
276227 if (metadata .hasSuperClass ()) {
277228 String superclass = metadata .getSuperClassName ();
278- if (this .knownSuperclasses .add (superclass )) {
229+ if (!this .knownSuperclasses .containsKey (superclass )) {
230+ this .knownSuperclasses .put (superclass , configClass );
279231 // superclass found, return its annotation metadata and recurse
280232 if (metadata instanceof StandardAnnotationMetadata ) {
281233 Class <?> clazz = ((StandardAnnotationMetadata ) metadata ).getIntrospectedClass ();
@@ -302,14 +254,6 @@ else if (superclass.startsWith("java")) {
302254 return null ;
303255 }
304256
305- private void addConfigurationClass (ConfigurationClass configClass ) {
306- this .configurationClasses .put (configClass ,configClass );
307- }
308-
309- private ConfigurationClass removeConfigurationClass (ConfigurationClass configClass ) {
310- return this .configurationClasses .remove (configClass );
311- }
312-
313257 /**
314258 * Register member (nested) classes that happen to be configuration classes themselves.
315259 * @param metadata the metadata representation of the containing class
@@ -500,13 +444,13 @@ private void invokeAwareMethods(ImportBeanDefinitionRegistrar registrar) {
500444 * @see ConfigurationClass#validate
501445 */
502446 public void validate () {
503- for (ConfigurationClass configClass : getConfigurationClasses () ) {
447+ for (ConfigurationClass configClass : this . configurationClasses ) {
504448 configClass .validate (this .problemReporter );
505449 }
506450 }
507451
508452 public Set <ConfigurationClass > getConfigurationClasses () {
509- return this .configurationClasses . keySet () ;
453+ return this .configurationClasses ;
510454 }
511455
512456 public Stack <PropertySource <?>> getPropertySources () {
0 commit comments