考虑以下测试用例:
@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)
我预计fooProperties.bar
会被填充,或者至少@NotNull
会抛出验证错误。
但是,在存在单参数构造函数 (1) 和冲突属性 (2) 的情况下(例如,它可能是完全不相关的系统环境变量),我得到以下结果:
fooProperties.bar
是null
- 没有抛出验证错误
发生这种情况是因为Binder
决定使用其单参数构造ObjectToObjectConverter
函数进行初始化FooProperties
(尽管事实上FooProperties
是在方法中显式创建的@Bean
),创建 的新实例FooProperties
并对它应用验证,但ConfigurationPropertiesBindingPostProcessor
忽略该新实例。
这适用于 Spring Boot 2.0.x、2.1.x、2.2.x。