Merge branch '2.2.x'

Closes gh-21444
This commit is contained in:
Phillip Webb 2020-05-13 19:11:29 -07:00
commit fd505e516f
4 changed files with 71 additions and 33 deletions

View File

@ -58,21 +58,21 @@ public class CloudFoundryWebEndpointDiscoverer extends WebEndpointDiscoverer {
}
@Override
protected boolean isExtensionExposed(Object extensionBean) {
if (isHealthEndpointExtension(extensionBean) && !isCloudFoundryHealthEndpointExtension(extensionBean)) {
protected boolean isExtensionTypeExposed(Class<?> extensionBeanType) {
if (isHealthEndpointExtension(extensionBeanType) && !isCloudFoundryHealthEndpointExtension(extensionBeanType)) {
// Filter regular health endpoint extensions so a CF version can replace them
return false;
}
return true;
}
private boolean isHealthEndpointExtension(Object extensionBean) {
return MergedAnnotations.from(extensionBean.getClass()).get(EndpointWebExtension.class)
private boolean isHealthEndpointExtension(Class<?> extensionBeanType) {
return MergedAnnotations.from(extensionBeanType).get(EndpointWebExtension.class)
.getValue("endpoint", Class.class).map(HealthEndpoint.class::isAssignableFrom).orElse(false);
}
private boolean isCloudFoundryHealthEndpointExtension(Object extensionBean) {
return MergedAnnotations.from(extensionBean.getClass()).isPresent(EndpointCloudFoundryExtension.class);
private boolean isCloudFoundryHealthEndpointExtension(Class<?> extensionBeanType) {
return MergedAnnotations.from(extensionBeanType).isPresent(EndpointCloudFoundryExtension.class);
}
}

View File

@ -49,6 +49,7 @@ import org.springframework.core.annotation.MergedAnnotations;
import org.springframework.core.annotation.MergedAnnotations.SearchStrategy;
import org.springframework.core.env.Environment;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.util.CollectionUtils;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
@ -140,8 +141,9 @@ public abstract class EndpointDiscoverer<E extends ExposableEndpoint<O>, O exten
}
private EndpointBean createEndpointBean(String beanName) {
Object bean = this.applicationContext.getBean(beanName);
return new EndpointBean(this.applicationContext.getEnvironment(), beanName, bean);
Class<?> beanType = ClassUtils.getUserClass(this.applicationContext.getType(beanName, false));
Supplier<Object> beanSupplier = () -> this.applicationContext.getBean(beanName);
return new EndpointBean(this.applicationContext.getEnvironment(), beanName, beanType, beanSupplier);
}
private void addExtensionBeans(Collection<EndpointBean> endpointBeans) {
@ -159,8 +161,9 @@ public abstract class EndpointDiscoverer<E extends ExposableEndpoint<O>, O exten
}
private ExtensionBean createExtensionBean(String beanName) {
Object bean = this.applicationContext.getBean(beanName);
return new ExtensionBean(this.applicationContext.getEnvironment(), beanName, bean);
Class<?> beanType = ClassUtils.getUserClass(this.applicationContext.getType(beanName));
Supplier<Object> beanSupplier = () -> this.applicationContext.getBean(beanName);
return new ExtensionBean(this.applicationContext.getEnvironment(), beanName, beanType, beanSupplier);
}
private void addExtensionBean(EndpointBean endpointBean, ExtensionBean extensionBean) {
@ -233,7 +236,8 @@ public abstract class EndpointDiscoverer<E extends ExposableEndpoint<O>, O exten
}
private boolean isExtensionExposed(EndpointBean endpointBean, ExtensionBean extensionBean) {
return isFilterMatch(extensionBean.getFilter(), endpointBean) && isExtensionExposed(extensionBean.getBean());
return isFilterMatch(extensionBean.getFilter(), endpointBean)
&& isExtensionTypeExposed(extensionBean.getBeanType());
}
/**
@ -242,10 +246,21 @@ public abstract class EndpointDiscoverer<E extends ExposableEndpoint<O>, O exten
* @param extensionBean the extension bean
* @return {@code true} if the extension is exposed
*/
@Deprecated
protected boolean isExtensionExposed(Object extensionBean) {
return true;
}
/**
* Determine if an extension bean should be exposed. Subclasses can override this
* method to provide additional logic.
* @param extensionBeanType the extension bean type
* @return {@code true} if the extension is exposed
*/
protected boolean isExtensionTypeExposed(Class<?> extensionBeanType) {
return true;
}
private boolean isEndpointExposed(EndpointBean endpointBean) {
return isFilterMatch(endpointBean.getFilter(), endpointBean) && !isEndpointFiltered(endpointBean)
&& isEndpointExposed(endpointBean.getBean());
@ -257,10 +272,21 @@ public abstract class EndpointDiscoverer<E extends ExposableEndpoint<O>, O exten
* @param endpointBean the endpoint bean
* @return {@code true} if the endpoint is exposed
*/
@Deprecated
protected boolean isEndpointExposed(Object endpointBean) {
return true;
}
/**
* Determine if an endpoint bean should be exposed. Subclasses can override this
* method to provide additional logic.
* @param beanType the endpoint bean type
* @return {@code true} if the endpoint is exposed
*/
protected boolean isEndpointTypeExposed(Class<?> beanType) {
return true;
}
private boolean isEndpointFiltered(EndpointBean endpointBean) {
for (EndpointFilter<E> filter : this.filters) {
if (!isFilterMatch(filter, endpointBean)) {
@ -272,7 +298,7 @@ public abstract class EndpointDiscoverer<E extends ExposableEndpoint<O>, O exten
@SuppressWarnings("unchecked")
private boolean isFilterMatch(Class<?> filter, EndpointBean endpointBean) {
if (!isEndpointExposed(endpointBean.getBean())) {
if (!isEndpointTypeExposed(endpointBean.getBeanType())) {
return false;
}
if (filter == null) {
@ -392,7 +418,9 @@ public abstract class EndpointDiscoverer<E extends ExposableEndpoint<O>, O exten
private final String beanName;
private final Object bean;
private final Class<?> beanType;
private final Supplier<Object> beanSupplier;
private final EndpointId id;
@ -402,17 +430,18 @@ public abstract class EndpointDiscoverer<E extends ExposableEndpoint<O>, O exten
private Set<ExtensionBean> extensions = new LinkedHashSet<>();
EndpointBean(Environment environment, String beanName, Object bean) {
MergedAnnotation<Endpoint> annotation = MergedAnnotations
.from(bean.getClass(), SearchStrategy.TYPE_HIERARCHY).get(Endpoint.class);
EndpointBean(Environment environment, String beanName, Class<?> beanType, Supplier<Object> beanSupplier) {
MergedAnnotation<Endpoint> annotation = MergedAnnotations.from(beanType, SearchStrategy.TYPE_HIERARCHY)
.get(Endpoint.class);
String id = annotation.getString("id");
Assert.state(StringUtils.hasText(id),
() -> "No @Endpoint id attribute specified for " + bean.getClass().getName());
() -> "No @Endpoint id attribute specified for " + beanType.getName());
this.beanName = beanName;
this.bean = bean;
this.beanType = beanType;
this.beanSupplier = beanSupplier;
this.id = EndpointId.of(environment, id);
this.enabledByDefault = annotation.getBoolean("enableByDefault");
this.filter = getFilter(this.bean.getClass());
this.filter = getFilter(beanType);
}
void addExtension(ExtensionBean extensionBean) {
@ -432,8 +461,12 @@ public abstract class EndpointDiscoverer<E extends ExposableEndpoint<O>, O exten
return this.beanName;
}
Class<?> getBeanType() {
return this.beanType;
}
Object getBean() {
return this.bean;
return this.beanSupplier.get();
}
EndpointId getId() {
@ -457,17 +490,20 @@ public abstract class EndpointDiscoverer<E extends ExposableEndpoint<O>, O exten
private final String beanName;
private final Object bean;
private final Class<?> beanType;
private final Supplier<Object> beanSupplier;
private final EndpointId endpointId;
private final Class<?> filter;
ExtensionBean(Environment environment, String beanName, Object bean) {
this.bean = bean;
ExtensionBean(Environment environment, String beanName, Class<?> beanType, Supplier<Object> beanSupplier) {
this.beanName = beanName;
this.beanType = beanType;
this.beanSupplier = beanSupplier;
MergedAnnotation<EndpointExtension> extensionAnnotation = MergedAnnotations
.from(bean.getClass(), SearchStrategy.TYPE_HIERARCHY).get(EndpointExtension.class);
.from(beanType, SearchStrategy.TYPE_HIERARCHY).get(EndpointExtension.class);
Class<?> endpointType = extensionAnnotation.getClass("endpoint");
MergedAnnotation<Endpoint> endpointAnnotation = MergedAnnotations
.from(endpointType, SearchStrategy.TYPE_HIERARCHY).get(Endpoint.class);
@ -481,8 +517,12 @@ public abstract class EndpointDiscoverer<E extends ExposableEndpoint<O>, O exten
return this.beanName;
}
Class<?> getBeanType() {
return this.beanType;
}
Object getBean() {
return this.bean;
return this.beanSupplier.get();
}
EndpointId getEndpointId() {

View File

@ -30,7 +30,7 @@ import org.springframework.boot.actuate.endpoint.invoke.ParameterValueMapper;
import org.springframework.boot.actuate.endpoint.web.PathMapper;
import org.springframework.context.ApplicationContext;
import org.springframework.core.annotation.MergedAnnotations;
import org.springframework.util.ClassUtils;
import org.springframework.core.annotation.MergedAnnotations.SearchStrategy;
/**
* {@link EndpointDiscoverer} for {@link ExposableControllerEndpoint controller
@ -57,9 +57,8 @@ public class ControllerEndpointDiscoverer extends EndpointDiscoverer<ExposableCo
}
@Override
protected boolean isEndpointExposed(Object endpointBean) {
Class<?> type = ClassUtils.getUserClass(endpointBean.getClass());
MergedAnnotations annotations = MergedAnnotations.from(type);
protected boolean isEndpointTypeExposed(Class<?> beanType) {
MergedAnnotations annotations = MergedAnnotations.from(beanType, SearchStrategy.SUPERCLASS);
return annotations.isPresent(ControllerEndpoint.class) || annotations.isPresent(RestControllerEndpoint.class);
}

View File

@ -31,7 +31,7 @@ import org.springframework.boot.actuate.endpoint.web.ExposableServletEndpoint;
import org.springframework.boot.actuate.endpoint.web.PathMapper;
import org.springframework.context.ApplicationContext;
import org.springframework.core.annotation.MergedAnnotations;
import org.springframework.util.ClassUtils;
import org.springframework.core.annotation.MergedAnnotations.SearchStrategy;
/**
* {@link EndpointDiscoverer} for {@link ExposableServletEndpoint servlet endpoints}.
@ -57,9 +57,8 @@ public class ServletEndpointDiscoverer extends EndpointDiscoverer<ExposableServl
}
@Override
protected boolean isEndpointExposed(Object endpointBean) {
Class<?> type = ClassUtils.getUserClass(endpointBean.getClass());
return MergedAnnotations.from(type).isPresent(ServletEndpoint.class);
protected boolean isEndpointTypeExposed(Class<?> beanType) {
return MergedAnnotations.from(beanType, SearchStrategy.SUPERCLASS).isPresent(ServletEndpoint.class);
}
@Override