Revised fix for SPR-12334, now finding duplicates at the collectImports level

Issue: SPR-12442
This commit is contained in:
Juergen Hoeller
2014-11-22 23:59:12 +01:00
parent feb6552d2c
commit 4b4bc2dae0

View File

@@ -23,7 +23,6 @@ import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.Map;
@@ -101,8 +100,6 @@ class ConfigurationClassParser {
private final ImportStack importStack = new ImportStack();
private final Set<Class<?>> importBeanDefinitionRegistrars = new HashSet<Class<?>>();
/**
* Create a new {@link ConfigurationClassParser} instance that will be used
@@ -202,7 +199,7 @@ class ConfigurationClassParser {
// Process any @Import annotations
Set<Object> imports = new LinkedHashSet<Object>();
Set<Object> visited = new LinkedHashSet<Object>();
Set<String> visited = new LinkedHashSet<String>();
collectImports(metadata, imports, visited);
if (!imports.isEmpty()) {
processImport(configClass, metadata, imports, true);
@@ -318,7 +315,7 @@ class ConfigurationClassParser {
* @param visited used to track visited classes to prevent infinite recursion
* @throws IOException if there is any problem reading metadata from the named class
*/
private void collectImports(AnnotationMetadata metadata, Set<Object> imports, Set<Object> visited) throws IOException {
private void collectImports(AnnotationMetadata metadata, Set<Object> imports, Set<String> visited) throws IOException {
String className = metadata.getClassName();
if (visited.add(className)) {
if (metadata instanceof StandardAnnotationMetadata) {
@@ -330,9 +327,13 @@ class ConfigurationClassParser {
}
Map<String, Object> attributes = stdMetadata.getAnnotationAttributes(Import.class.getName(), false);
if (attributes != null) {
Class[] value = (Class[]) attributes.get("value");
Class<?>[] value = (Class<?>[]) attributes.get("value");
if (!ObjectUtils.isEmpty(value)) {
imports.addAll(Arrays.asList(value));
for (Class<?> importedClass : value) {
// Catch duplicate from ASM-based parsing...
imports.remove(importedClass.getName());
imports.add(importedClass);
}
}
}
}
@@ -345,7 +346,7 @@ class ConfigurationClassParser {
imports, visited);
}
catch (ClassNotFoundException ex) {
//
// Silently ignore...
}
}
}
@@ -353,7 +354,19 @@ class ConfigurationClassParser {
if (attributes != null) {
String[] value = (String[]) attributes.get("value");
if (!ObjectUtils.isEmpty(value)) {
imports.addAll(Arrays.asList(value));
for (String importedClassName : value) {
// Catch duplicate from reflection-based parsing...
boolean alreadyThereAsClass = false;
for (Object existingImport : imports) {
if (existingImport instanceof Class &&
((Class<?>) existingImport).getName().equals(importedClassName)) {
alreadyThereAsClass = true;
}
}
if (!alreadyThereAsClass) {
imports.add(importedClassName);
}
}
}
}
}
@@ -384,13 +397,10 @@ class ConfigurationClassParser {
// delegate to it to register additional bean definitions
Class<?> candidateClass = (candidate instanceof Class ? (Class) candidate :
this.resourceLoader.getClassLoader().loadClass((String) candidate));
if (!this.importBeanDefinitionRegistrars.contains(candidateClass)) {
ImportBeanDefinitionRegistrar registrar =
BeanUtils.instantiateClass(candidateClass, ImportBeanDefinitionRegistrar.class);
invokeAwareMethods(registrar);
registrar.registerBeanDefinitions(metadata, this.registry);
this.importBeanDefinitionRegistrars.add(candidateClass);
}
ImportBeanDefinitionRegistrar registrar =
BeanUtils.instantiateClass(candidateClass, ImportBeanDefinitionRegistrar.class);
invokeAwareMethods(registrar);
registrar.registerBeanDefinitions(metadata, this.registry);
}
else {
// Candidate class not an ImportSelector or ImportBeanDefinitionRegistrar ->