From 3416e058a01d80d22c52c8c6fb720454be4c4290 Mon Sep 17 00:00:00 2001 From: Phillip Webb Date: Wed, 31 Oct 2012 13:38:34 +0100 Subject: [PATCH] Ensure @Imports are processed in correct order Issue: SPR-9925 --- .../annotation/ConfigurationClassParser.java | 28 ++++++++++++------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/spring-context/src/main/java/org/springframework/context/annotation/ConfigurationClassParser.java b/spring-context/src/main/java/org/springframework/context/annotation/ConfigurationClassParser.java index 2690c5b03e..53f573bcb0 100644 --- a/spring-context/src/main/java/org/springframework/context/annotation/ConfigurationClassParser.java +++ b/spring-context/src/main/java/org/springframework/context/annotation/ConfigurationClassParser.java @@ -24,6 +24,7 @@ import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.LinkedHashSet; +import java.util.LinkedList; import java.util.Map; import java.util.Set; import java.util.Stack; @@ -72,6 +73,8 @@ import static org.springframework.context.annotation.MetadataUtils.*; */ class ConfigurationClassParser { + private static final String[] EMPTY_IMPORTS = {}; + private final MetadataReaderFactory metadataReaderFactory; private final ProblemReporter problemReporter; @@ -221,10 +224,7 @@ class ConfigurationClassParser { } // process any @Import annotations - Set imports = getImports(metadata.getClassName(), null, new HashSet()); - if (imports != null && !imports.isEmpty()) { - processImport(configClass, imports.toArray(new String[imports.size()]), true); - } + processImport(configClass, getImports(metadata.getClassName()), true); // process any @ImportResource annotations if (metadata.isAnnotated(ImportResource.class.getName())) { @@ -276,23 +276,31 @@ class ConfigurationClassParser { * @return a set of all {@link Import#value() import values} or {@code null} * @throws IOException if there is any problem reading metadata from the named class */ - private Set getImports(String className, Set imports, + private String[] getImports(String className) throws IOException { + LinkedList imports = new LinkedList(); + collectImports(className, imports, new HashSet()); + if(imports == null || imports.isEmpty()) { + return EMPTY_IMPORTS; + } + LinkedHashSet uniqueImports = new LinkedHashSet(imports); + return uniqueImports.toArray(new String[uniqueImports.size()]); + } + + private void collectImports(String className, LinkedList imports, Set visited) throws IOException { if (visited.add(className)) { AnnotationMetadata metadata = metadataReaderFactory.getMetadataReader(className).getAnnotationMetadata(); + for (String annotationType : metadata.getAnnotationTypes()) { + collectImports(annotationType, imports, visited); + } Map attributes = metadata.getAnnotationAttributes(Import.class.getName(), true); if (attributes != null) { String[] value = (String[]) attributes.get("value"); if (value != null && value.length > 0) { - imports = (imports == null ? new LinkedHashSet() : imports); imports.addAll(Arrays.asList(value)); } } - for (String annotationType : metadata.getAnnotationTypes()) { - getImports(annotationType, imports, visited); - } } - return imports; } private void processImport(ConfigurationClass configClass, String[] classesToImport, boolean checkForCircularImports) throws IOException {