|
|
|
@ -19,6 +19,7 @@ package org.springframework.boot.endpoint;
|
|
|
|
|
import java.lang.annotation.Annotation;
|
|
|
|
|
import java.lang.reflect.Method;
|
|
|
|
|
import java.util.ArrayList;
|
|
|
|
|
import java.util.Arrays;
|
|
|
|
|
import java.util.Collection;
|
|
|
|
|
import java.util.Collections;
|
|
|
|
|
import java.util.HashMap;
|
|
|
|
@ -28,6 +29,8 @@ import java.util.Map;
|
|
|
|
|
import java.util.function.Consumer;
|
|
|
|
|
import java.util.function.Function;
|
|
|
|
|
|
|
|
|
|
import org.springframework.beans.factory.HierarchicalBeanFactory;
|
|
|
|
|
import org.springframework.beans.factory.ListableBeanFactory;
|
|
|
|
|
import org.springframework.context.ApplicationContext;
|
|
|
|
|
import org.springframework.core.MethodIntrospector;
|
|
|
|
|
import org.springframework.core.annotation.AnnotatedElementUtils;
|
|
|
|
@ -35,6 +38,7 @@ import org.springframework.core.annotation.AnnotationAttributes;
|
|
|
|
|
import org.springframework.util.Assert;
|
|
|
|
|
import org.springframework.util.LinkedMultiValueMap;
|
|
|
|
|
import org.springframework.util.ObjectUtils;
|
|
|
|
|
import org.springframework.util.StringUtils;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* A base {@link EndpointDiscoverer} implementation that discovers {@link Endpoint} beans
|
|
|
|
@ -88,8 +92,8 @@ public abstract class AnnotationEndpointDiscoverer<T extends Operation, K>
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private Map<Class<?>, EndpointInfo<T>> discoverEndpoints(EndpointExposure exposure) {
|
|
|
|
|
String[] beanNames = this.applicationContext
|
|
|
|
|
.getBeanNamesForAnnotation(Endpoint.class);
|
|
|
|
|
String[] beanNames = beanNamesForAnnotationIncludingAncestors(
|
|
|
|
|
this.applicationContext, Endpoint.class);
|
|
|
|
|
Map<Class<?>, EndpointInfo<T>> endpoints = new LinkedHashMap<>();
|
|
|
|
|
Map<String, EndpointInfo<T>> endpointsById = new LinkedHashMap<>();
|
|
|
|
|
for (String beanName : beanNames) {
|
|
|
|
@ -121,8 +125,8 @@ public abstract class AnnotationEndpointDiscoverer<T extends Operation, K>
|
|
|
|
|
if (extensionType == null) {
|
|
|
|
|
return Collections.emptyMap();
|
|
|
|
|
}
|
|
|
|
|
String[] beanNames = this.applicationContext
|
|
|
|
|
.getBeanNamesForAnnotation(extensionType);
|
|
|
|
|
String[] beanNames = beanNamesForAnnotationIncludingAncestors(
|
|
|
|
|
this.applicationContext, extensionType);
|
|
|
|
|
Map<Class<?>, EndpointExtensionInfo<T>> extensions = new HashMap<>();
|
|
|
|
|
for (String beanName : beanNames) {
|
|
|
|
|
Class<?> beanType = this.applicationContext.getType(beanName);
|
|
|
|
@ -150,6 +154,28 @@ public abstract class AnnotationEndpointDiscoverer<T extends Operation, K>
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private static String[] beanNamesForAnnotationIncludingAncestors(
|
|
|
|
|
ListableBeanFactory lbf, Class<? extends Annotation> annotationType) {
|
|
|
|
|
Assert.notNull(lbf, "ListableBeanFactory must not be null");
|
|
|
|
|
String[] result = lbf.getBeanNamesForAnnotation(annotationType);
|
|
|
|
|
if (lbf instanceof HierarchicalBeanFactory) {
|
|
|
|
|
HierarchicalBeanFactory hbf = (HierarchicalBeanFactory) lbf;
|
|
|
|
|
if (hbf.getParentBeanFactory() instanceof ListableBeanFactory) {
|
|
|
|
|
String[] parentResult = beanNamesForAnnotationIncludingAncestors(
|
|
|
|
|
(ListableBeanFactory) hbf.getParentBeanFactory(), annotationType);
|
|
|
|
|
List<String> resultList = new ArrayList<>();
|
|
|
|
|
resultList.addAll(Arrays.asList(result));
|
|
|
|
|
for (String beanName : parentResult) {
|
|
|
|
|
if (!resultList.contains(beanName) && !hbf.containsLocalBean(beanName)) {
|
|
|
|
|
resultList.add(beanName);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
result = StringUtils.toStringArray(resultList);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private EndpointInfo<T> getEndpointInfo(Map<Class<?>, EndpointInfo<T>> endpoints,
|
|
|
|
|
Class<?> beanType, Class<?> endpointClass) {
|
|
|
|
|
EndpointInfo<T> endpoint = endpoints.get(endpointClass);
|
|
|
|
|