Browse Source

ConfigurationClassParser detects @Bean methods in interface hierarchies as well

Issue: SPR-14288
pull/1067/head
Juergen Hoeller 9 years ago
parent
commit
03affa02db
  1. 28
      spring-context/src/main/java/org/springframework/context/annotation/ConfigurationClassParser.java
  2. 20
      spring-context/src/test/java/org/springframework/context/annotation/ConfigurationClassPostProcessorTests.java

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

@ -303,15 +303,7 @@ class ConfigurationClassParser { @@ -303,15 +303,7 @@ class ConfigurationClassParser {
}
// Process default methods on interfaces
for (SourceClass ifc : sourceClass.getInterfaces()) {
beanMethods = ifc.getMetadata().getAnnotatedMethods(Bean.class.getName());
for (MethodMetadata methodMetadata : beanMethods) {
if (!methodMetadata.isAbstract()) {
// A default method or other concrete method on a Java 8+ interface...
configClass.addBeanMethod(new BeanMethod(methodMetadata, configClass));
}
}
}
processInterfaces(configClass, sourceClass);
// Process superclass, if any
if (sourceClass.getMetadata().hasSuperClass()) {
@ -329,8 +321,6 @@ class ConfigurationClassParser { @@ -329,8 +321,6 @@ class ConfigurationClassParser {
/**
* Register member (nested) classes that happen to be configuration classes themselves.
* @param sourceClass the source class to process
* @throws IOException if there is any problem reading metadata from a member class
*/
private void processMemberClasses(ConfigurationClass configClass, SourceClass sourceClass) throws IOException {
for (SourceClass memberClass : sourceClass.getMemberClasses()) {
@ -352,6 +342,22 @@ class ConfigurationClassParser { @@ -352,6 +342,22 @@ class ConfigurationClassParser {
}
}
/**
* Register default methods on interfaces implemented by the configuration class.
*/
private void processInterfaces(ConfigurationClass configClass, SourceClass sourceClass) throws IOException {
for (SourceClass ifc : sourceClass.getInterfaces()) {
Set<MethodMetadata> beanMethods = ifc.getMetadata().getAnnotatedMethods(Bean.class.getName());
for (MethodMetadata methodMetadata : beanMethods) {
if (!methodMetadata.isAbstract()) {
// A default method or other concrete method on a Java 8+ interface...
configClass.addBeanMethod(new BeanMethod(methodMetadata, configClass));
}
}
processInterfaces(configClass, ifc);
}
}
/**
* Process the given <code>@PropertySource</code> annotation metadata.
* @param propertySource metadata for the <code>@PropertySource</code> annotation found

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

@ -1063,17 +1063,27 @@ public class ConfigurationClassPostProcessorTests { @@ -1063,17 +1063,27 @@ public class ConfigurationClassPostProcessorTests {
}
}
public interface DefaultMethodsConfig {
public interface BaseInterface {
@Bean
default ServiceBean serviceBean() {
return provider().getServiceBean();
}
ServiceBean serviceBean();
}
public interface BaseDefaultMethods extends BaseInterface {
@Bean
default ServiceBeanProvider provider() {
return new ServiceBeanProvider();
}
@Bean
@Override
default ServiceBean serviceBean() {
return provider().getServiceBean();
}
}
public interface DefaultMethodsConfig extends BaseDefaultMethods {
}
@Configuration

Loading…
Cancel
Save