我有两种工厂方法:
@Bean
@ConditionalOnProperty("some.property.text")
public Apple createAppleX() {}
和
@Bean
@ConditionalOnProperty("some.property.text", matchIfMissing=true)
public Apple createAppleY() {}
如果没有“some.property.text”属性 - 第二种方法工作正常,第一种方法被忽略,这是理想的行为。
如果我们将某些字符串设置为“some.property.text” - 这两种方法都被认为对生成Apple对象有效,这导致应用程序失败并显示错误“没有类型的限定bean”。
如果我们对该属性有一些价值,是否可以避免将第二种方法视为工厂方法?特别是,只能通过注释吗?
答案 0 :(得分:3)
您可以使用NoneNestedConditions
来否定一个或多个嵌套条件。像这样:
class NoSomePropertyCondition extends NoneNestedConditions {
NoSomePropertyCondition() {
super(ConfigurationPhase.PARSE_CONFIGURATION);
}
@ConditionalOnProperty("some.property.text")
static class SomePropertyCondition {
}
}
然后,您可以在其中一个bean方法上使用此自定义条件:
@Bean
@ConditionalOnProperty("some.property.text")
public Apple createAppleX() {}
@Bean
@Conditional(NoSomePropertyCondition.class)
public Apple createAppleY() {}
答案 1 :(得分:2)
我遇到了同样的问题,这是我的解决方案:
@Bean
@ConditionalOnProperty("some.property.text")
public Apple createAppleX() {}
@Bean
@ConditionalOnProperty("some.property.text", matchIfMissing=true, havingValue="value_that_never_appears")
public Apple createAppleY() {}
答案 2 :(得分:0)
本着一臂之力的精神,这是一个更具可重用性的注释:
@Conditional(ConditionalOnMissingProperty.MissingPropertyCondition.class)
public @interface ConditionalOnMissingProperty {
String PROPERTY_KEYS = "propertyKeys";
@AliasFor(PROPERTY_KEYS)
String[] value() default {};
@AliasFor("value")
String[] propertyKeys() default {};
class MissingPropertyCondition extends SpringBootCondition {
@Override
public ConditionOutcome getMatchOutcome(ConditionContext context, AnnotatedTypeMetadata metadata) {
String[] keys = (String[]) metadata.getAnnotationAttributes(ConditionalOnMissingProperty.class.getName()).get(PROPERTY_KEYS);
if (keys.length > 0) {
boolean allMissing = true;
for (String key : keys) {
String propertyValue = context.getEnvironment().getProperty(key);
String propertyValueList = context.getEnvironment().getProperty(key + "[0]"); //in case of list
allMissing &= (StringUtils.isEmpty(propertyValue) || StringUtils.isEmpty(propertyValueList));
}
if (allMissing) {
return new ConditionOutcome(true, "The following properties were all null or empty in the environment: " + Arrays.toString(keys));
}
return new ConditionOutcome(false, "one or more properties were found.");
} else {
throw new RuntimeException("expected method annotated with " + ConditionalOnMissingProperty.class.getName() + " to include a non-empty " + PROPERTY_KEYS + " attribute");
}
}
}
}
当一个或多个提到的属性全部不存在时,会激活带注释的bean或配置:
@ConditionalOnMissingProperty({"app.foo.bar"})
@Configuration
public class SomeConfiguration {
//... won't run if there is an app.foo.bar property with non-empty contents.
}
稍后,如果我将更全面的报告添加到错误的结果中,则将其添加到此处。