diff --git a/spring-boot-project/spring-boot-actuator/pom.xml b/spring-boot-project/spring-boot-actuator/pom.xml
index c18b3ce871..cedc88716c 100644
--- a/spring-boot-project/spring-boot-actuator/pom.xml
+++ b/spring-boot-project/spring-boot-actuator/pom.xml
@@ -345,6 +345,11 @@
log4j-to-slf4j
test
+
+ org.apache.tomcat.embed
+ tomcat-embed-el
+ test
+
org.glassfish.jersey.media
jersey-media-json-jackson
diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/context/properties/ConfigurationPropertiesReportEndpoint.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/context/properties/ConfigurationPropertiesReportEndpoint.java
index f09686b299..88a51d12c8 100644
--- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/context/properties/ConfigurationPropertiesReportEndpoint.java
+++ b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/context/properties/ConfigurationPropertiesReportEndpoint.java
@@ -310,7 +310,8 @@ public class ConfigurationPropertiesReportEndpoint implements ApplicationContext
public List changeProperties(SerializationConfig config, BeanDescription beanDesc,
List beanProperties) {
List result = new ArrayList<>();
- Constructor> bindConstructor = findBindConstructor(beanDesc.getType().getRawClass());
+ Class> beanClass = beanDesc.getType().getRawClass();
+ Constructor> bindConstructor = findBindConstructor(ClassUtils.getUserClass(beanClass));
for (BeanPropertyWriter writer : beanProperties) {
if (isCandidate(beanDesc, writer, bindConstructor)) {
result.add(writer);
diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/context/properties/ConfigurationPropertiesReportEndpointProxyTests.java b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/context/properties/ConfigurationPropertiesReportEndpointProxyTests.java
index 9a1a3c46f1..61c7a82709 100644
--- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/context/properties/ConfigurationPropertiesReportEndpointProxyTests.java
+++ b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/context/properties/ConfigurationPropertiesReportEndpointProxyTests.java
@@ -16,6 +16,8 @@
package org.springframework.boot.actuate.context.properties;
+import java.util.Map;
+
import javax.sql.DataSource;
import org.junit.jupiter.api.Test;
@@ -27,6 +29,7 @@ import org.springframework.boot.context.properties.EnableConfigurationProperties
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Import;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType;
@@ -35,6 +38,7 @@ import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
+import org.springframework.validation.beanvalidation.MethodValidationPostProcessor;
import static org.assertj.core.api.Assertions.assertThat;
@@ -44,6 +48,7 @@ import static org.assertj.core.api.Assertions.assertThat;
*
* @author Phillip Webb
* @author Andy Wilkinson
+ * @author Madhura Bhave
*/
class ConfigurationPropertiesReportEndpointProxyTests {
@@ -60,6 +65,19 @@ class ConfigurationPropertiesReportEndpointProxyTests {
});
}
+ @Test
+ void proxiedConstructorBoundPropertiesShouldBeAvailableInReport() {
+ ApplicationContextRunner contextRunner = new ApplicationContextRunner()
+ .withUserConfiguration(ValidatedConfiguration.class).withPropertyValues("validated.name=baz");
+ contextRunner.run((context) -> {
+ ApplicationConfigurationProperties applicationProperties = context
+ .getBean(ConfigurationPropertiesReportEndpoint.class).configurationProperties();
+ Map properties = applicationProperties.getContexts().get(context.getId()).getBeans()
+ .values().stream().map(ConfigurationPropertiesBeanDescriptor::getProperties).findFirst().get();
+ assertThat(properties.get("name")).isEqualTo("baz");
+ });
+ }
+
@Configuration(proxyBeanMethods = false)
@EnableTransactionManagement(proxyTargetClass = false)
@EnableConfigurationProperties
@@ -75,6 +93,11 @@ class ConfigurationPropertiesReportEndpointProxyTests {
return new DataSourceTransactionManager(dataSource);
}
+ @Bean
+ MethodValidationPostProcessor testPostProcessor() {
+ return new MethodValidationPostProcessor();
+ }
+
@Bean
DataSource dataSource() {
return new EmbeddedDatabaseBuilder().setType(EmbeddedDatabaseType.HSQL).build();
@@ -103,4 +126,11 @@ class ConfigurationPropertiesReportEndpointProxyTests {
}
+ @Configuration(proxyBeanMethods = false)
+ @EnableConfigurationProperties(ValidatedConstructorBindingProperties.class)
+ @Import(Config.class)
+ static class ValidatedConfiguration {
+
+ }
+
}
diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/context/properties/ValidatedConstructorBindingProperties.java b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/context/properties/ValidatedConstructorBindingProperties.java
new file mode 100644
index 0000000000..3bb8722ad4
--- /dev/null
+++ b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/context/properties/ValidatedConstructorBindingProperties.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2012-2019 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.boot.actuate.context.properties;
+
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.boot.context.properties.ConstructorBinding;
+import org.springframework.validation.annotation.Validated;
+
+/**
+ * Used for testing the {@link ConfigurationPropertiesReportEndpoint} endpoint with
+ * validated {@link ConfigurationProperties @ConfigurationProperties}.
+ *
+ * @author Madhura Bhave
+ */
+@Validated
+@ConstructorBinding
+@ConfigurationProperties(prefix = "validated")
+public class ValidatedConstructorBindingProperties {
+
+ private final String name;
+
+ ValidatedConstructorBindingProperties(String name) {
+ this.name = name;
+ }
+
+ public String getName() {
+ return this.name;
+ }
+
+}