有没有办法使用基于多值属性的@ConditionalOnProperty注释?
Spring配置:
@Bean
@ConditionalOnProperty(name = "prop", havingValue = "a")
public SomeBean bean1() {
return new SomeBean1();
}
@Bean
@ConditionalOnProperty(name = "prop", havingValue = "b")
public SomeBean bean2() {
return new SomeBean2();
}
和application.yaml
prop:
- a
- b
我希望两个bean:bean1和bean2都将在spring上下文中注册,但是没有人注册。有没有办法做到这一点?
答案 0 :(得分:2)
看起来@ConditionalOnProperty没有多元化的特性。 在春天的环境中,它们被表示为
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.TYPE, ElementType.METHOD })
@Documented
@Conditional(OnPropertyCondition.class)
public @interface ConditionalOnProperty2 {
String name();
String value();
}
我的解决方案是创建自己的@Conditional扩展,它可以使用多值属性。这是一个例子。
注释:
class OnPropertyCondition implements Condition {
@Override
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
String name = attribute(metadata, "name");
String value = attribute(metadata, "value");
String searchName = name;
String property = property(context, searchName);
int i = 0;
do {
if (value.equals(property)) return true;
searchName = name + '[' + i++ + ']';
} while ((property = property(context, searchName)) != null);
return false;
}
private String attribute(AnnotatedTypeMetadata metadata, String name) {
return (String) metadata.getAnnotationAttributes(ConditionalOnProperty2.class.getName()).get(name);
}
private String property(ConditionContext context, String name) {
return context.getEnvironment().getProperty(name);
}
}
条件:
@Bean
@ConditionalOnProperty2(name = "prop", havingValue = "a")
public SomeBean bean1() {
return new SomeBean1();
}
@Bean
@ConditionalOnProperty2(name = "prop", havingValue = "b")
public SomeBean bean2() {
return new SomeBean2();
}
用法:
{{1}}
答案 1 :(得分:1)
您可以使用Spring Boot @ConditionalOnExpression批注,不仅可以在@ bean-annotated方法中使用,还可以直接在类上使用:
@ConditionalOnExpression("${my.prop}")
@Component
class SomeBean1 implements SomeBean {}
@ConditionalOnExpression("!${my.prop}")
@Component
class SomeBean2 implements SomeBean {}
话虽如此,我个人更喜欢使用纯Java:
@Value("${my.prop}") String myProp;
...
@Bean SomeBean someBean() {
if ("abc".equals(myProp)) {return new SomeBean1();} else {return new SomeBean2();}
}