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