diff --git a/spring-cloud-context/src/main/java/org/springframework/cloud/bootstrap/BootstrapImportSelector.java b/spring-cloud-context/src/main/java/org/springframework/cloud/bootstrap/BootstrapImportSelector.java index 6215cd11..c6f9daf4 100644 --- a/spring-cloud-context/src/main/java/org/springframework/cloud/bootstrap/BootstrapImportSelector.java +++ b/spring-cloud-context/src/main/java/org/springframework/cloud/bootstrap/BootstrapImportSelector.java @@ -16,18 +16,25 @@ package org.springframework.cloud.bootstrap; +import java.io.IOException; +import java.lang.annotation.Annotation; +import java.lang.reflect.AnnotatedElement; import java.util.ArrayList; import java.util.Arrays; import java.util.List; -import java.util.stream.Collectors; +import java.util.Map; import org.springframework.context.EnvironmentAware; import org.springframework.context.annotation.DeferredImportSelector; import org.springframework.core.annotation.AnnotationAwareOrderComparator; +import org.springframework.core.annotation.Order; import org.springframework.core.env.Environment; import org.springframework.core.io.support.SpringFactoriesLoader; +import org.springframework.core.style.ToStringCreator; import org.springframework.core.type.AnnotationMetadata; -import org.springframework.util.ClassUtils; +import org.springframework.core.type.classreading.CachingMetadataReaderFactory; +import org.springframework.core.type.classreading.MetadataReader; +import org.springframework.core.type.classreading.MetadataReaderFactory; import org.springframework.util.StringUtils; /** @@ -41,13 +48,15 @@ public class BootstrapImportSelector implements EnvironmentAware, DeferredImport private Environment environment; + private MetadataReaderFactory metadataReaderFactory = new CachingMetadataReaderFactory(); + @Override public void setEnvironment(Environment environment) { this.environment = environment; } @Override - public String[] selectImports(AnnotationMetadata metadata) { + public String[] selectImports(AnnotationMetadata annotationMetadata) { ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); // Use names and ensure unique to protect against duplicates List names = new ArrayList<>(SpringFactoriesLoader @@ -55,24 +64,75 @@ public class BootstrapImportSelector implements EnvironmentAware, DeferredImport names.addAll(Arrays.asList(StringUtils.commaDelimitedListToStringArray( environment.getProperty("spring.cloud.bootstrap.sources", "")))); - List> sources = new ArrayList<>(); + List elements = new ArrayList<>(); for (String name : names) { - Class cls = ClassUtils.resolveClassName(name, null); try { - cls.getDeclaredAnnotations(); - } - catch (Exception e) { + elements.add(new OrderedAnnotatedElement(metadataReaderFactory, name)); + } catch (IOException e) { continue; } - sources.add(cls); } - AnnotationAwareOrderComparator.sort(sources); + AnnotationAwareOrderComparator.sort(elements); - List classNames = sources.stream() - .map(Class::getName) - .collect(Collectors.toList()); + String[] classNames = elements.stream() + .map(e -> e.name) + .toArray(String[]::new); + return classNames; + } - return classNames.toArray(new String[0]); + class OrderedAnnotatedElement implements AnnotatedElement { + + private final String name; + private Order order = null; + private Integer value; + + public OrderedAnnotatedElement(MetadataReaderFactory metadataReaderFactory, String name) throws IOException { + MetadataReader metadataReader = metadataReaderFactory.getMetadataReader(name); + AnnotationMetadata metadata = metadataReader.getAnnotationMetadata(); + Map attributes = metadata.getAnnotationAttributes(Order.class.getName()); + this.name = name; + if (attributes != null && attributes.containsKey("value")) { + value = (Integer) attributes.get("value"); + order = new Order() { + @Override + public Class annotationType() { + return Order.class; + } + + @Override + public int value() { + return value; + } + }; + } + } + + @Override + @SuppressWarnings("unchecked") + public T getAnnotation(Class annotationClass) { + if (annotationClass == Order.class) { + return (T) order; + } + return null; + } + + @Override + public Annotation[] getAnnotations() { + return new Annotation[]{order}; + } + + @Override + public Annotation[] getDeclaredAnnotations() { + return getAnnotations(); + } + + @Override + public String toString() { + return new ToStringCreator(this) + .append("name", name) + .append("value", value) + .toString(); + } } }