Spring-boot ConditionalOnProperty具有基于地图的属性

时间:2016-05-05 18:14:14

标签: spring-boot

我的spring-boot yaml属性如下所示:

service:
    mycomponent:
        foo: 
            url: http://foo
        bar:
            url: http://bar

这导致在Spring环境中设置以下属性:

service.mycomponent.foo.url: http://foo
service.mycomponent.bar.url: http://bar

我想定义一个' mycomponent' bean,如果有任何匹配service.mycomponent.[a-z]*.url的属性。这可能是使用@ConditionalOnExpression或其他类型的@Conditional吗?

我意识到我可以通过添加可以与service.mycomponent.enabled: true一起使用的@ConditionalOnProperty这样的属性来解决这个问题,但是如果可能的话我宁愿避免这种情况。

1 个答案:

答案 0 :(得分:4)

以下是我最终采取的解决方案:

创建自定义Condition,搜索具有特定前缀的任何属性。 RelaxedPropertyResolver具有方便的getSubProperties()方法。我发现的替代选项很难迭代PropertySource个实例。

public class MyComponentCondition extends SpringBootCondition {
    @Override
    public ConditionOutcome getMatchOutcome(final ConditionContext context,
                                            final AnnotatedTypeMetadata metadata) {
        final RelaxedPropertyResolver resolver = new RelaxedPropertyResolver(context.getEnvironment());
        final Map<String, Object> properties = resolver.getSubProperties("service.mycomponent.");
        return new ConditionOutcome(!properties.isEmpty(), "My Component");
    }
}

设置bean时使用该条件:

@Conditional(MyComponentCondition.class)
@Bean
public MyComponent myComponent() {
    return new MyComponent();
}

我仍然很好奇是否可以直接使用@ConditionalOnExpression完成同样的事情。