spring @多值属性的ConditionalOnProperty

wgmfuz8q  于 2022-11-21  发布在  Spring
关注(0)|答案(3)|浏览(717)

是否有任何方法可以使用基于多值属性的@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();
}

和应用程序。

prop: 
 - a
 - b

我既料到豆子:bean 1和bean 2将在spring上下文中注册,但它们中没有一个未注册。

kwvwclae

kwvwclae1#

您可以使用Sping Boot @ConditionalOnExpression注解,不仅可以在@ bean注解的方法中使用,也可以直接在类上使用:

@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();}
}
7uzetpgm

7uzetpgm2#

@ConditionalOnProperty似乎没有多值属性。在Spring环境中,它们显示为

prop[0]=a
prop[1]=b

我的解决方案是创建我自己的@Conditional扩展,它能够处理多值属性。下面是一个例子。
注解:

@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.TYPE, ElementType.METHOD })
@Documented
@Conditional(OnPropertyCondition.class)
public @interface ConditionalOnProperty2 {
    String name();
    String value();
}

条件:

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();
 }
lsmepo6l

lsmepo6l3#

havingValue并不意味着一个对象有这个值,它意味着我们从这个键得到的值是否等于havingValue
因此,列表对象prop既不等于a,也不等于b,它等于[a, b]

相关问题