Skip to content

Commit 180ab2d

Browse files
committed
Merge branch '1.4.x' into 1.5.x
2 parents f34d309 + f3b9b14 commit 180ab2d

File tree

3 files changed

+85
-22
lines changed

3 files changed

+85
-22
lines changed

spring-boot-actuator/src/main/java/org/springframework/boot/actuate/autoconfigure/ManagementContextConfiguration.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2015 the original author or authors.
2+
* Copyright 2012-2017 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -23,15 +23,21 @@
2323
import java.lang.annotation.Target;
2424

2525
import org.springframework.context.annotation.Configuration;
26+
import org.springframework.core.Ordered;
27+
import org.springframework.core.annotation.Order;
2628

2729
/**
2830
* Specialized {@link Configuration @Configuration} class that defines configuration
2931
* specific for the management context. Configurations should be registered in
3032
* {@code /META-INF/spring.factories} under the
3133
* {@code org.springframework.boot.actuate.autoconfigure.ManagementContextConfiguration}
3234
* key.
35+
* <p>
36+
* {@code ManagementContextConfiguration} classes can be ordered using {@link Order}.
37+
* Ordering by implementing {@link Ordered} is not supported and will have no effect.
3338
*
3439
* @author Phillip Webb
40+
* @author Andy Wilkinson
3541
* @since 1.3.0
3642
*/
3743
@Target(ElementType.TYPE)

spring-boot-actuator/src/main/java/org/springframework/boot/actuate/autoconfigure/ManagementContextConfigurationsImportSelector.java

Lines changed: 70 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -16,19 +16,20 @@
1616

1717
package org.springframework.boot.actuate.autoconfigure;
1818

19+
import java.io.IOException;
1920
import java.util.ArrayList;
20-
import java.util.LinkedHashSet;
2121
import java.util.List;
22-
import java.util.Set;
22+
import java.util.Map;
2323

2424
import org.springframework.beans.factory.BeanClassLoaderAware;
2525
import org.springframework.context.annotation.DeferredImportSelector;
26+
import org.springframework.core.OrderComparator;
2627
import org.springframework.core.Ordered;
27-
import org.springframework.core.annotation.AnnotationAwareOrderComparator;
2828
import org.springframework.core.annotation.Order;
2929
import org.springframework.core.io.support.SpringFactoriesLoader;
3030
import org.springframework.core.type.AnnotationMetadata;
31-
import org.springframework.util.ClassUtils;
31+
import org.springframework.core.type.classreading.MetadataReader;
32+
import org.springframework.core.type.classreading.SimpleMetadataReaderFactory;
3233

3334
/**
3435
* Selects configuration classes for the management context configuration. Entries are
@@ -38,6 +39,7 @@
3839
*
3940
* @author Dave Syer
4041
* @author Phillip Webb
42+
* @author Andy Wilkinson
4143
* @see ManagementContextConfiguration
4244
*/
4345
@Order(Ordered.LOWEST_PRECEDENCE)
@@ -48,32 +50,81 @@ class ManagementContextConfigurationsImportSelector
4850

4951
@Override
5052
public String[] selectImports(AnnotationMetadata metadata) {
51-
// Find all possible auto configuration classes, filtering duplicates
52-
List<String> names = loadFactoryNames();
53-
Set<Class<?>> classes = new LinkedHashSet<Class<?>>();
54-
for (String factoryName : names) {
55-
classes.add(ClassUtils.resolveClassName(factoryName, this.classLoader));
53+
// Find all management context configuration classes, filtering duplicates
54+
List<ManagementConfiguration> configurations = getConfigurations();
55+
OrderComparator.sort(configurations);
56+
List<String> names = new ArrayList<String>();
57+
for (ManagementConfiguration configuration : configurations) {
58+
names.add(configuration.getClassName());
5659
}
57-
return getSortedClassNames(new ArrayList<Class<?>>(classes));
60+
return names.toArray(new String[names.size()]);
5861
}
5962

60-
protected List<String> loadFactoryNames() {
61-
return SpringFactoriesLoader
62-
.loadFactoryNames(ManagementContextConfiguration.class, this.classLoader);
63+
private List<ManagementConfiguration> getConfigurations() {
64+
SimpleMetadataReaderFactory readerFactory = new SimpleMetadataReaderFactory(
65+
this.classLoader);
66+
List<ManagementConfiguration> configurations = new ArrayList<ManagementConfiguration>();
67+
for (String className : loadFactoryNames()) {
68+
getConfiguration(readerFactory, configurations, className);
69+
}
70+
return configurations;
6371
}
6472

65-
private String[] getSortedClassNames(List<Class<?>> classes) {
66-
AnnotationAwareOrderComparator.sort(classes);
67-
List<String> names = new ArrayList<String>();
68-
for (Class<?> sourceClass : classes) {
69-
names.add(sourceClass.getName());
73+
private void getConfiguration(SimpleMetadataReaderFactory readerFactory,
74+
List<ManagementConfiguration> configurations, String className) {
75+
try {
76+
MetadataReader metadataReader = readerFactory.getMetadataReader(className);
77+
configurations.add(new ManagementConfiguration(metadataReader));
7078
}
71-
return names.toArray(new String[names.size()]);
79+
catch (IOException ex) {
80+
throw new RuntimeException(
81+
"Failed to read annotation metadata for '" + className + "'", ex);
82+
}
83+
}
84+
85+
protected List<String> loadFactoryNames() {
86+
return SpringFactoriesLoader
87+
.loadFactoryNames(ManagementContextConfiguration.class, this.classLoader);
7288
}
7389

7490
@Override
7591
public void setBeanClassLoader(ClassLoader classLoader) {
7692
this.classLoader = classLoader;
7793
}
7894

95+
/**
96+
* A management configuration class which can be sorted according to {@code @Order}.
97+
*/
98+
private static final class ManagementConfiguration implements Ordered {
99+
100+
private final String className;
101+
102+
private final int order;
103+
104+
ManagementConfiguration(MetadataReader metadataReader) {
105+
AnnotationMetadata annotationMetadata = metadataReader
106+
.getAnnotationMetadata();
107+
this.order = readOrder(annotationMetadata);
108+
this.className = metadataReader.getClassMetadata().getClassName();
109+
}
110+
111+
private int readOrder(AnnotationMetadata annotationMetadata) {
112+
Map<String, Object> attributes = annotationMetadata
113+
.getAnnotationAttributes(Order.class.getName());
114+
Integer order = (attributes == null ? null
115+
: (Integer) attributes.get("value"));
116+
return (order == null ? Ordered.LOWEST_PRECEDENCE : order);
117+
}
118+
119+
public String getClassName() {
120+
return this.className;
121+
}
122+
123+
@Override
124+
public int getOrder() {
125+
return this.order;
126+
}
127+
128+
}
129+
79130
}

spring-boot-actuator/src/test/java/org/springframework/boot/actuate/autoconfigure/ManagementContextConfigurationsImportSelectorTests.java

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
* Tests for {@link ManagementContextConfigurationsImportSelector}.
3030
*
3131
* @author Phillip Webb
32+
* @author Andy Wilkinson
3233
*/
3334
public class ManagementContextConfigurationsImportSelectorTests {
3435

@@ -37,15 +38,16 @@ public void selectImportsShouldOrderResult() throws Exception {
3738
String[] imports = new TestManagementContextConfigurationsImportSelector()
3839
.selectImports(null);
3940
assertThat(imports).containsExactly(A.class.getName(), B.class.getName(),
40-
C.class.getName());
41+
C.class.getName(), D.class.getName());
4142
}
4243

4344
private static class TestManagementContextConfigurationsImportSelector
4445
extends ManagementContextConfigurationsImportSelector {
4546

4647
@Override
4748
protected List<String> loadFactoryNames() {
48-
return Arrays.asList(C.class.getName(), A.class.getName(), B.class.getName());
49+
return Arrays.asList(C.class.getName(), A.class.getName(), D.class.getName(),
50+
B.class.getName());
4951
}
5052

5153
}
@@ -65,4 +67,8 @@ private static class C {
6567

6668
}
6769

70+
static class D {
71+
72+
}
73+
6874
}

0 commit comments

Comments
 (0)