Skip to content

Commit 6de14f7

Browse files
committed
Fail fast if config prop constructor binding cannot determine names
Previously, configuration property constructor binding relied on compilation with -parameters to be able to discover the names of a constructor's parameters, failing silently if the parameter names were not available. This commit updates it to fail when the names could not be determined and switches to using DefaultParameterNamesDiscoverer. This align configuration property constructor binding with actuator endpoint operation invocation. Closes gh-16928
1 parent b603cd5 commit 6de14f7

File tree

1 file changed

+18
-6
lines changed

1 file changed

+18
-6
lines changed

spring-boot-project/spring-boot/src/main/java/org/springframework/boot/context/properties/bind/ConstructorParametersBinder.java

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,11 @@
3232

3333
import org.springframework.beans.BeanUtils;
3434
import org.springframework.boot.context.properties.source.ConfigurationPropertyName;
35+
import org.springframework.core.DefaultParameterNameDiscoverer;
3536
import org.springframework.core.KotlinDetector;
37+
import org.springframework.core.ParameterNameDiscoverer;
3638
import org.springframework.core.ResolvableType;
39+
import org.springframework.util.Assert;
3740

3841
/**
3942
* {@link BeanBinder} for constructor based binding.
@@ -164,10 +167,13 @@ private static Map<String, ConstructorParameter> parseParameters(
164167
}
165168

166169
/**
167-
* A simple bean provider that uses `-parameters` to extract the parameter names.
170+
* A simple bean provider that uses {@link DefaultParameterNameDiscoverer} to extract
171+
* the parameter names.
168172
*/
169173
private static class SimpleBeanProvider {
170174

175+
private static final ParameterNameDiscoverer PARAMETER_NAME_DISCOVERER = new DefaultParameterNameDiscoverer();
176+
171177
public static Bean get(Class<?> type) {
172178
Constructor<?>[] constructors = type.getDeclaredConstructors();
173179
if (constructors.length == 1 && constructors[0].getParameterCount() > 0) {
@@ -182,19 +188,25 @@ public static Bean get(Constructor<?> constructor) {
182188

183189
private static Map<String, ConstructorParameter> parseParameters(
184190
Constructor<?> constructor) {
185-
Map<String, ConstructorParameter> parameters = new LinkedHashMap<>();
186-
for (Parameter parameter : constructor.getParameters()) {
187-
String name = parameter.getName();
191+
String[] parameterNames = PARAMETER_NAME_DISCOVERER
192+
.getParameterNames(constructor);
193+
Assert.state(parameterNames != null,
194+
() -> "Failed to extract parameter names for " + constructor);
195+
Map<String, ConstructorParameter> parametersByName = new LinkedHashMap<>();
196+
Parameter[] parameters = constructor.getParameters();
197+
for (int i = 0; i < parameterNames.length; i++) {
198+
String name = parameterNames[i];
199+
Parameter parameter = parameters[i];
188200
DefaultValue[] annotationsByType = parameter
189201
.getAnnotationsByType(DefaultValue.class);
190202
String[] defaultValue = (annotationsByType.length > 0)
191203
? annotationsByType[0].value() : null;
192-
parameters.computeIfAbsent(name,
204+
parametersByName.computeIfAbsent(name,
193205
(key) -> new ConstructorParameter(name,
194206
ResolvableType.forClass(parameter.getType()),
195207
parameter.getDeclaredAnnotations(), defaultValue));
196208
}
197-
return parameters;
209+
return parametersByName;
198210
}
199211

200212
}

0 commit comments

Comments
 (0)