Fix error message when constructor binding fails to create bean

The configuration property is always cleared before bean instantiation
because the problem with bean instantiation might not necessarily be the
last bound property.

Fixes gh-18704
This commit is contained in:
Madhura Bhave
2019-10-25 12:45:38 -07:00
parent 533ca0624f
commit dec6ee20d4
3 changed files with 40 additions and 1 deletions

View File

@@ -551,7 +551,7 @@ public class Binder {
this.configurationProperty = configurationProperty;
}
private void clearConfigurationProperty() {
void clearConfigurationProperty() {
this.configurationProperty = null;
}

View File

@@ -61,6 +61,7 @@ class ValueObjectBinder implements DataObjectBinder {
arg = (arg != null) ? arg : parameter.getDefaultValue(context.getConverter());
args.add(arg);
}
context.clearConfigurationProperty();
return bound ? valueObject.instantiate(args) : null;
}

View File

@@ -21,6 +21,7 @@ import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import com.atomikos.util.Assert;
import org.junit.jupiter.api.Test;
import org.springframework.boot.context.properties.source.ConfigurationPropertyName;
@@ -29,6 +30,7 @@ import org.springframework.boot.context.properties.source.MockConfigurationPrope
import org.springframework.format.annotation.DateTimeFormat;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
/**
* Tests for {@link ValueObjectBinder}.
@@ -220,6 +222,20 @@ class ValueObjectBinderTests {
assertThat(bean.getDate().toString()).isEqualTo("2019-05-10");
}
@Test
void bindWhenAllPropertiesBoundShouldClearConfigurationProperty() { // gh-18704
MockConfigurationPropertySource source = new MockConfigurationPropertySource();
source.put("foo.bar", "hello");
this.sources.add(source);
Bindable<ValidatingConstructorBean> target = Bindable.of(ValidatingConstructorBean.class);
assertThatExceptionOfType(BindException.class).isThrownBy(() -> this.binder.bind("foo", target))
.satisfies(this::noConfigurationProperty);
}
private void noConfigurationProperty(BindException ex) {
assertThat(ex.getProperty()).isNull();
}
static class ExampleValueBean {
private final int intValue;
@@ -413,4 +429,26 @@ class ValueObjectBinderTests {
}
static class ValidatingConstructorBean {
private final String foo;
private final String bar;
ValidatingConstructorBean(String foo, String bar) {
Assert.notNull("Foo must not be null", foo);
this.foo = foo;
this.bar = bar;
}
String getFoo() {
return this.foo;
}
String getBar() {
return this.bar;
}
}
}