-
Notifications
You must be signed in to change notification settings - Fork 41.5k
Closed
Description
Consider the following test case:
@RunWith(SpringRunner.class)
@SpringBootTest(classes = { BindingTest.Config.class })
@EnableConfigurationProperties
@TestPropertySource
public class BindingTest {
@Autowired FooProperties fooProperties;
@Test
public void shouldInjectBar() {
assertThat(fooProperties.getBar()).isEqualTo("baz");
}
@Configuration
public static class Config {
@Bean
public FooProperties fooProperties() {
return new FooProperties();
}
}
@ConfigurationProperties("foo")
@Validated
public static class FooProperties {
@NotNull @Getter @Setter
private String bar;
public FooProperties() {}
public FooProperties(String bar) { // (1)
this.bar = bar;
}
}
}
BindingTest.properties
:
foo.bar=baz
foo=unrelated # (2)
I expected fooProperties.bar
to be populated, or, at least, @NotNull
validation error to be thrown.
However, in presence of single argument constructor (1) and conflicting property (2) (it may be, for example, a totally unrelated system environment variable), I got the following:
fooProperties.bar
isnull
- no validation error is thrown
This happens because Binder
decides to use ObjectToObjectConverter
to initialize FooProperties
using its single argument constructor (despite the fact that FooProperties
is explicitly created in @Bean
method), creates new instance of FooProperties
and applies validation to it, but ConfigurationPropertiesBindingPostProcessor
ignores that new instance.
This applies to Spring Boot 2.0.x, 2.1.x, 2.2.x.
Metadata
Metadata
Labels
type: bugA general bugA general bug