Skip to content

Commit fa5d246

Browse files
committed
Replace all exposed superclasses in final step after traversal
See gh-28676
1 parent aeb77cf commit fa5d246

File tree

2 files changed

+36
-14
lines changed

2 files changed

+36
-14
lines changed

Diff for: spring-context/src/main/java/org/springframework/context/annotation/ConfigurationClassParser.java

+23-13
Original file line numberDiff line numberDiff line change
@@ -468,6 +468,9 @@ private Set<MethodMetadata> retrieveBeanMethodMetadata(SourceClass sourceClass)
468468
* the superclass exposure on a different config class with the same superclass.
469469
*/
470470
private void removeKnownSuperclass(String removedClass, boolean replace) {
471+
String replacedSuperclass = null;
472+
ConfigurationClass replacingClass = null;
473+
471474
Iterator<Map.Entry<String, List<ConfigurationClass>>> it = this.knownSuperclasses.entrySet().iterator();
472475
while (it.hasNext()) {
473476
Map.Entry<String, List<ConfigurationClass>> entry = it.next();
@@ -476,22 +479,29 @@ private void removeKnownSuperclass(String removedClass, boolean replace) {
476479
it.remove();
477480
}
478481
else if (replace) {
479-
try {
480-
ConfigurationClass otherClass = entry.getValue().get(0);
481-
SourceClass sourceClass = asSourceClass(otherClass, DEFAULT_EXCLUSION_FILTER).getSuperClass();
482-
while (!sourceClass.getMetadata().getClassName().equals(entry.getKey()) &&
483-
sourceClass.getMetadata().getSuperClassName() != null) {
484-
sourceClass = sourceClass.getSuperClass();
485-
}
486-
doProcessConfigurationClass(otherClass, sourceClass, DEFAULT_EXCLUSION_FILTER);
487-
}
488-
catch (IOException ex) {
489-
throw new BeanDefinitionStoreException(
490-
"I/O failure while removing configuration class [" + removedClass + "]", ex);
491-
}
482+
replacedSuperclass = entry.getKey();
483+
replacingClass = entry.getValue().get(0);
492484
}
493485
}
494486
}
487+
488+
if (replacingClass != null) {
489+
try {
490+
SourceClass sourceClass = asSourceClass(replacingClass, DEFAULT_EXCLUSION_FILTER).getSuperClass();
491+
while (!sourceClass.getMetadata().getClassName().equals(replacedSuperclass) &&
492+
sourceClass.getMetadata().getSuperClassName() != null) {
493+
sourceClass = sourceClass.getSuperClass();
494+
}
495+
do {
496+
sourceClass = doProcessConfigurationClass(replacingClass, sourceClass, DEFAULT_EXCLUSION_FILTER);
497+
}
498+
while (sourceClass != null);
499+
}
500+
catch (IOException ex) {
501+
throw new BeanDefinitionStoreException(
502+
"I/O failure while removing configuration class [" + removedClass + "]", ex);
503+
}
504+
}
495505
}
496506

497507
/**

Diff for: spring-context/src/test/java/org/springframework/context/annotation/configuration/ConfigurationPhasesKnownSuperclassesTests.java

+13-1
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131

3232
/**
3333
* @author Andy Wilkinson
34+
* @author Juergen Hoeller
3435
* @since 6.2
3536
*/
3637
class ConfigurationPhasesKnownSuperclassesTests {
@@ -40,6 +41,7 @@ void superclassSkippedInParseConfigurationPhaseShouldNotPreventSubsequentProcess
4041
try (AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(ParseConfigurationPhase.class)) {
4142
assertThat(context.getBean("subclassBean")).isEqualTo("bravo");
4243
assertThat(context.getBean("superclassBean")).isEqualTo("superclass");
44+
assertThat(context.getBean("baseBean")).isEqualTo("base");
4345
}
4446
}
4547

@@ -48,12 +50,22 @@ void superclassSkippedInRegisterBeanPhaseShouldNotPreventSubsequentProcessingOfS
4850
try (AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(RegisterBeanPhase.class)) {
4951
assertThat(context.getBean("subclassBean")).isEqualTo("bravo");
5052
assertThat(context.getBean("superclassBean")).isEqualTo("superclass");
53+
assertThat(context.getBean("baseBean")).isEqualTo("base");
5154
}
5255
}
5356

5457

5558
@Configuration(proxyBeanMethods = false)
56-
static class Example {
59+
static class Base {
60+
61+
@Bean
62+
String baseBean() {
63+
return "base";
64+
}
65+
}
66+
67+
@Configuration(proxyBeanMethods = false)
68+
static class Example extends Base {
5769

5870
@Bean
5971
String superclassBean() {

0 commit comments

Comments
 (0)