给定下面的示例,我预计不会调用MyConfig.getSrvConfig()
,因此也不会对返回的对象执行任何验证。但由于某些原因,验证被执行,测试用例失败。这个设置有什么问题吗?
我知道如果private MySrvConfigBean srvConfig
在声明时没有初始化,测试就会通过——但我真的不希望MySrvConfigBean
是一个带有@ConfigurationProperties(prefix = "cfg.srvConfig")
注释的独立类。
@RunWith(SpringRunner.class)
@ContextConfiguration(classes = { TestCaseConfiguration.class })
public class ConditionalConfigValidationTest {
@Autowired
private ApplicationContext applicationContext;
@Test
public void test() {
assertNotNull(applicationContext);
assertFalse("srvConfig must NOT be in context", applicationContext.containsBean("srvConfig"));
}
@Configuration
@EnableConfigurationProperties(value = { MyConfig.class })
public static class TestCaseConfiguration {
}
@Component
@Validated
@ConfigurationProperties(prefix = "cfg")
public static class MyConfig {
private MySrvConfigBean srvConfig = new MySrvConfigBean();
@Bean
@Valid
@Conditional(MyCondition.class)
public MySrvConfigBean getSrvConfig() {
return srvConfig;
}
public static class MySrvConfigBean {
@NotNull
private String name;
public String getName() {
return name;
}
}
}
public static class MyCondition implements Condition {
@Override
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
return false;
}
}
}
我们希望采用这种方式的原因是,因为我们能够以与YAML文件中相同的方式在代码中构建配置,例如:(cfg
和cfgA
是两个不同配置层次结构的"根"对象)。
cfg:
srvConfig:
name: Dude
clientConfig:
xxx: true
yyy: Muster
cfgA:
aaaConfig:
bbb: false
ccc: Dundy
dddConfig:
fff: 3
在这种情况下,感觉验证的执行(由@Valid
在getSrvConfig()
上触发)是一个错误。
显然,这是不受支持的,应该以不同的方式解决:
@Configuration
@Conditional(MyCondition.class)
@EnableConfigurationProperties(value = { MyConfig.class })
public static class TestCaseConfiguration {
}