springspring-annotations

Using @Conditional Spring annotation without knowing the whole property name


I want to optionally enable a @Configuration, based on whether a type of application.properties property exists or not. However I will not know the whole property name in advance, only part of its prefix i.e.

spring.security.oauth2.<provider-name>.url=x.y.z

And the goal is to enable the configuration using something like:

@ConditionalOnProperty(prefix = "spring.security", value="oauth2.*")

or something like that but it doesn't seem to work. I've tried multiple combinations, none work it always expects the full property name but I don't know the <provider-name> in advance. Any ways to achieve this functionality?


Solution

  • As of right now Spring does not support the requested functionality with the out of the box annotations which means a custom @Conditional condition must be created that does what we want. The Condition implementation looks like this:

    public class EnableOAuth2Condition implements Condition {
      @Override
      public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
        Environment env = context.getEnvironment();
        for(Iterator it = ((AbstractEnvironment) env).getPropertySources().iterator(); it.hasNext(); ) {
          PropertySource propertySource = (PropertySource) it.next();
          if (propertySource instanceof MapPropertySource) {
            for (String propertyName : ((MapPropertySource) propertySource).getSource().keySet()) {
              if(propertyName.startsWith("spring.security.oauth2")) {
                return true;
              }
            }
          }
        }
        return false;
      }
    }
    

    and the way to use it on a @Configuration class is the following:

    @Configuration
    @Conditional(EnableOAuth2Condition.class)
    public class MyOAuth2Config {
      ...
    }
    

    A bit messy for something simple but that's the way to go for now.