Skip to content

Commit 26f143b

Browse files
committed
Support @name annotation on /actuator/configprops
Update `ConfigurationPropertiesReportEndpoint` so that supports constructor parameters annotated with `@Name`. Fixes gh-24713
1 parent 6c2ff56 commit 26f143b

File tree

2 files changed

+31
-13
lines changed

2 files changed

+31
-13
lines changed

spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/context/properties/ConfigurationPropertiesReportEndpoint.java

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2020 the original author or authors.
2+
* Copyright 2012-2021 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.
@@ -17,6 +17,7 @@
1717
package org.springframework.boot.actuate.context.properties;
1818

1919
import java.lang.reflect.Constructor;
20+
import java.lang.reflect.Parameter;
2021
import java.util.ArrayList;
2122
import java.util.Arrays;
2223
import java.util.Collection;
@@ -58,12 +59,16 @@
5859
import org.springframework.boot.context.properties.ConfigurationProperties;
5960
import org.springframework.boot.context.properties.ConfigurationPropertiesBean;
6061
import org.springframework.boot.context.properties.ConstructorBinding;
62+
import org.springframework.boot.context.properties.bind.Name;
6163
import org.springframework.boot.context.properties.source.ConfigurationProperty;
6264
import org.springframework.boot.context.properties.source.ConfigurationPropertyName;
6365
import org.springframework.boot.origin.Origin;
6466
import org.springframework.context.ApplicationContext;
6567
import org.springframework.context.ApplicationContextAware;
68+
import org.springframework.core.DefaultParameterNameDiscoverer;
6669
import org.springframework.core.KotlinDetector;
70+
import org.springframework.core.ParameterNameDiscoverer;
71+
import org.springframework.core.annotation.MergedAnnotation;
6772
import org.springframework.core.annotation.MergedAnnotations;
6873
import org.springframework.core.annotation.MergedAnnotations.SearchStrategy;
6974
import org.springframework.util.ClassUtils;
@@ -384,6 +389,8 @@ public void serializeAsField(Object pojo, JsonGenerator jgen, SerializerProvider
384389
*/
385390
protected static class GenericSerializerModifier extends BeanSerializerModifier {
386391

392+
private static final ParameterNameDiscoverer PARAMETER_NAME_DISCOVERER = new DefaultParameterNameDiscoverer();
393+
387394
@Override
388395
public List<BeanPropertyWriter> changeProperties(SerializationConfig config, BeanDescription beanDesc,
389396
List<BeanPropertyWriter> beanProperties) {
@@ -398,11 +405,21 @@ public List<BeanPropertyWriter> changeProperties(SerializationConfig config, Bea
398405
return result;
399406
}
400407

401-
private boolean isCandidate(BeanDescription beanDesc, BeanPropertyWriter writer,
402-
Constructor<?> bindConstructor) {
403-
if (bindConstructor != null) {
404-
return Arrays.stream(bindConstructor.getParameters())
405-
.anyMatch((parameter) -> parameter.getName().equals(writer.getName()));
408+
private boolean isCandidate(BeanDescription beanDesc, BeanPropertyWriter writer, Constructor<?> constructor) {
409+
if (constructor != null) {
410+
Parameter[] parameters = constructor.getParameters();
411+
String[] names = PARAMETER_NAME_DISCOVERER.getParameterNames(constructor);
412+
if (names == null) {
413+
names = new String[parameters.length];
414+
}
415+
for (int i = 0; i < parameters.length; i++) {
416+
String name = MergedAnnotations.from(parameters[i]).get(Name.class)
417+
.getValue(MergedAnnotation.VALUE, String.class)
418+
.orElse((names[i] != null) ? names[i] : parameters[i].getName());
419+
if (name.equals(writer.getName())) {
420+
return true;
421+
}
422+
}
406423
}
407424
return isReadable(beanDesc, writer);
408425
}

spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/context/properties/ConfigurationPropertiesReportEndpointTests.java

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2020 the original author or authors.
2+
* Copyright 2012-2021 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.
@@ -34,6 +34,7 @@
3434
import org.springframework.boot.context.properties.ConstructorBinding;
3535
import org.springframework.boot.context.properties.EnableConfigurationProperties;
3636
import org.springframework.boot.context.properties.bind.DefaultValue;
37+
import org.springframework.boot.context.properties.bind.Name;
3738
import org.springframework.boot.origin.Origin;
3839
import org.springframework.boot.origin.OriginLookup;
3940
import org.springframework.boot.test.context.assertj.AssertableApplicationContext;
@@ -73,7 +74,7 @@ void descriptorWithJavaBeanBindMethodDetectsRelevantProperties() {
7374
void descriptorWithValueObjectBindMethodDetectsRelevantProperties() {
7475
this.contextRunner.withUserConfiguration(ImmutablePropertiesConfiguration.class).run(assertProperties(
7576
"immutable",
76-
(properties) -> assertThat(properties).containsOnlyKeys("dbPassword", "myTestProperty", "duration")));
77+
(properties) -> assertThat(properties).containsOnlyKeys("dbPassword", "myTestProperty", "for")));
7778
}
7879

7980
@Test
@@ -451,16 +452,16 @@ public static class ImmutableProperties {
451452

452453
private final String nullValue;
453454

454-
private final Duration duration;
455+
private final Duration forDuration;
455456

456457
private final String ignored;
457458

458459
ImmutableProperties(@DefaultValue("123456") String dbPassword, @DefaultValue("654321") String myTestProperty,
459-
String nullValue, @DefaultValue("10s") Duration duration) {
460+
String nullValue, @DefaultValue("10s") @Name("for") Duration forDuration) {
460461
this.dbPassword = dbPassword;
461462
this.myTestProperty = myTestProperty;
462463
this.nullValue = nullValue;
463-
this.duration = duration;
464+
this.forDuration = forDuration;
464465
this.ignored = "dummy";
465466
}
466467

@@ -476,8 +477,8 @@ public String getNullValue() {
476477
return this.nullValue;
477478
}
478479

479-
public Duration getDuration() {
480-
return this.duration;
480+
public Duration getFor() {
481+
return this.forDuration;
481482
}
482483

483484
public String getIgnored() {

0 commit comments

Comments
 (0)