Search code examples
springspring-bootspring-autoconfiguration

Using @ConditionalOnProperty with regex prefix patterns spring boot


I have a configuration class in my spring boot application which I want to enable only if certain properties in my application.properties file matches it.

@Configuration
@ConditionalOnProperty(prefix = "^sites\\[.*\\].*", name = "^prefix.*")
public class TestConfiguration {

    @Bean
    @Primary
    public TestManager getTestManager() {
        System.out.println("Created TestManager"); //just for debugging purposes
        return new TestManager();
    }
}

In my application.properties file I have a set of properties as below:

sites[0].id=site1
sites[0].name=site1 name
sites[0].datasource.url=
sites[0].datasource.user=

sites[1].id=site2
sites[1].name=site2 name
sites[1].datasource.url=
sites[1].datasource.user=
.
.
site[n].... so on

I want to create my TestManager bean only if these properties are present. When I try to have regex pattern on my prefix attribute it's not working out. What is the correct way of handling such situations? Is there any better approach for this problem?


Solution

  • I found a way to achieve the desired result by creating a custom Condition class and adding the logic to iterate through each of my application.properties file properties and see if it matches the regex pattern or not.

    public class CustomCondition implements Condition {
    
        @Override
        public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
            Optional<String> sitesProperty  = ((AbstractEnvironment)context.getEnvironment()).getPropertySources().stream()
                    .filter(propertySource -> propertySource instanceof EnumerablePropertySource)
                    .map(propertySource -> (EnumerablePropertySource) propertySource)
                    .flatMap(propertySource -> Arrays.stream(propertySource.getPropertyNames()))
                    .distinct()
                    .filter(propertyName -> propertyName.matches("^sites\\S\\d\\S.*"))
                    .findAny();
    
            return sitesProperty.isPresent();
        }
    }