Skip to content

Commit 62199e8

Browse files
committed
ConfigurationClassParser detects @bean methods in interface hierarchies as well
Issue: SPR-14288 (cherry picked from commit 03affa0)
1 parent 7de2976 commit 62199e8

File tree

2 files changed

+32
-16
lines changed

2 files changed

+32
-16
lines changed

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

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -295,15 +295,7 @@ protected final SourceClass doProcessConfigurationClass(ConfigurationClass confi
295295
}
296296

297297
// Process default methods on interfaces
298-
for (SourceClass ifc : sourceClass.getInterfaces()) {
299-
beanMethods = ifc.getMetadata().getAnnotatedMethods(Bean.class.getName());
300-
for (MethodMetadata methodMetadata : beanMethods) {
301-
if (!methodMetadata.isAbstract()) {
302-
// A default method or other concrete method on a Java 8+ interface...
303-
configClass.addBeanMethod(new BeanMethod(methodMetadata, configClass));
304-
}
305-
}
306-
}
298+
processInterfaces(configClass, sourceClass);
307299

308300
// Process superclass, if any
309301
if (sourceClass.getMetadata().hasSuperClass()) {
@@ -321,8 +313,6 @@ protected final SourceClass doProcessConfigurationClass(ConfigurationClass confi
321313

322314
/**
323315
* Register member (nested) classes that happen to be configuration classes themselves.
324-
* @param sourceClass the source class to process
325-
* @throws IOException if there is any problem reading metadata from a member class
326316
*/
327317
private void processMemberClasses(ConfigurationClass configClass, SourceClass sourceClass) throws IOException {
328318
for (SourceClass memberClass : sourceClass.getMemberClasses()) {
@@ -344,6 +334,22 @@ private void processMemberClasses(ConfigurationClass configClass, SourceClass so
344334
}
345335
}
346336

337+
/**
338+
* Register default methods on interfaces implemented by the configuration class.
339+
*/
340+
private void processInterfaces(ConfigurationClass configClass, SourceClass sourceClass) throws IOException {
341+
for (SourceClass ifc : sourceClass.getInterfaces()) {
342+
Set<MethodMetadata> beanMethods = ifc.getMetadata().getAnnotatedMethods(Bean.class.getName());
343+
for (MethodMetadata methodMetadata : beanMethods) {
344+
if (!methodMetadata.isAbstract()) {
345+
// A default method or other concrete method on a Java 8+ interface...
346+
configClass.addBeanMethod(new BeanMethod(methodMetadata, configClass));
347+
}
348+
}
349+
processInterfaces(configClass, ifc);
350+
}
351+
}
352+
347353
/**
348354
* Process the given <code>@PropertySource</code> annotation metadata.
349355
* @param propertySource metadata for the <code>@PropertySource</code> annotation found

spring-context/src/test/java/org/springframework/context/annotation/ConfigurationClassPostProcessorTests.java

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1063,17 +1063,27 @@ public void validate() {
10631063
}
10641064
}
10651065

1066-
public interface DefaultMethodsConfig {
1066+
public interface BaseInterface {
10671067

1068-
@Bean
1069-
default ServiceBean serviceBean() {
1070-
return provider().getServiceBean();
1071-
}
1068+
ServiceBean serviceBean();
1069+
}
1070+
1071+
public interface BaseDefaultMethods extends BaseInterface {
10721072

10731073
@Bean
10741074
default ServiceBeanProvider provider() {
10751075
return new ServiceBeanProvider();
10761076
}
1077+
1078+
@Bean
1079+
@Override
1080+
default ServiceBean serviceBean() {
1081+
return provider().getServiceBean();
1082+
}
1083+
}
1084+
1085+
public interface DefaultMethodsConfig extends BaseDefaultMethods {
1086+
10771087
}
10781088

10791089
@Configuration

0 commit comments

Comments
 (0)