ConfigurationClassParser enforces @Bean declaration order through ASM metadata
Issue: SPR-14505
This commit is contained in:
parent
8147c112f5
commit
3295a4e6ef
|
|
@ -291,7 +291,7 @@ class ConfigurationClassParser {
|
|||
}
|
||||
|
||||
// Process individual @Bean methods
|
||||
Set<MethodMetadata> beanMethods = sourceClass.getMetadata().getAnnotatedMethods(Bean.class.getName());
|
||||
Set<MethodMetadata> beanMethods = retrieveBeanMethodMetadata(sourceClass);
|
||||
for (MethodMetadata methodMetadata : beanMethods) {
|
||||
configClass.addBeanMethod(new BeanMethod(methodMetadata, configClass));
|
||||
}
|
||||
|
|
@ -341,7 +341,7 @@ class ConfigurationClassParser {
|
|||
*/
|
||||
private void processInterfaces(ConfigurationClass configClass, SourceClass sourceClass) throws IOException {
|
||||
for (SourceClass ifc : sourceClass.getInterfaces()) {
|
||||
Set<MethodMetadata> beanMethods = ifc.getMetadata().getAnnotatedMethods(Bean.class.getName());
|
||||
Set<MethodMetadata> beanMethods = retrieveBeanMethodMetadata(ifc);
|
||||
for (MethodMetadata methodMetadata : beanMethods) {
|
||||
if (!methodMetadata.isAbstract()) {
|
||||
// A default method or other concrete method on a Java 8+ interface...
|
||||
|
|
@ -352,6 +352,29 @@ class ConfigurationClassParser {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the metadata for all <code>@Bean</code> methods.
|
||||
*/
|
||||
private Set<MethodMetadata> retrieveBeanMethodMetadata(SourceClass sourceClass) {
|
||||
AnnotationMetadata original = sourceClass.getMetadata();
|
||||
Set<MethodMetadata> beanMethods = original.getAnnotatedMethods(Bean.class.getName());
|
||||
if (beanMethods.size() > 1 && original instanceof StandardAnnotationMetadata) {
|
||||
// Try reading the class file via ASM for deterministic declaration order...
|
||||
// Unfortunately, the JVM's standard reflection returns methods in arbitrary
|
||||
// order, even between different runs of the same application on the same JVM.
|
||||
try {
|
||||
AnnotationMetadata asm =
|
||||
this.metadataReaderFactory.getMetadataReader(original.getClassName()).getAnnotationMetadata();
|
||||
beanMethods = asm.getAnnotatedMethods(Bean.class.getName());
|
||||
}
|
||||
catch (IOException ex) {
|
||||
logger.debug("Failed to read class file via ASM for determining @Bean method order", ex);
|
||||
// No worries, let's continue with the reflection metadata we started with...
|
||||
}
|
||||
}
|
||||
return beanMethods;
|
||||
}
|
||||
|
||||
/**
|
||||
* Process the given <code>@PropertySource</code> annotation metadata.
|
||||
* @param propertySource metadata for the <code>@PropertySource</code> annotation found
|
||||
|
|
@ -588,7 +611,7 @@ class ConfigurationClassParser {
|
|||
if (metadata instanceof StandardAnnotationMetadata) {
|
||||
return asSourceClass(((StandardAnnotationMetadata) metadata).getIntrospectedClass());
|
||||
}
|
||||
return asSourceClass(configurationClass.getMetadata().getClassName());
|
||||
return asSourceClass(metadata.getClassName());
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -1281,15 +1281,15 @@ public class ConfigurationClassPostProcessorTests {
|
|||
@Configuration
|
||||
static class FooBarConfiguration {
|
||||
|
||||
@Bean @DependsOn("bar")
|
||||
public FooImpl foo() {
|
||||
return new FooImpl();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public BarInterface bar() {
|
||||
return new BarImpl();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public FooImpl foo() {
|
||||
return new FooImpl();
|
||||
}
|
||||
}
|
||||
|
||||
@Configuration
|
||||
|
|
|
|||
Loading…
Reference in New Issue