Spring: How to do AND in Profiles?

java, spring, spring-profiles

Solution

Since Spring does not provide the AND feature out of the box. I would suggest the following strategy:

Currently `@Profile` annotation has a conditional annotation `@Conditional(ProfileCondition.class)`. In `ProfileCondition.class` it iterates through the profiles and checks if the profile is active. Similarly you could create your own conditional implementation and restrict registering the bean. e.g.

public class MyProfileCondition implements Condition {

    @Override
    public boolean matches(final ConditionContext context,
            final AnnotatedTypeMetadata metadata) {
        if (context.getEnvironment() != null) {
            final MultiValueMap<String, Object> attrs = metadata.getAllAnnotationAttributes(Profile.class.getName());
            if (attrs != null) {
                for (final Object value : attrs.get("value")) {
                    final String activeProfiles = context.getEnvironment().getProperty("spring.profiles.active");

                    for (final String profile : (String[]) value) {
                        if (!activeProfiles.contains(profile)) {
                            return false;
                        }
                    }
                }
                return true;
            }
        }
        return true;
    }

}

In your class:

@Component
@Profile("dev")
@Conditional(value = { MyProfileCondition.class })
public class DevDatasourceConfig

NOTE: I have not checked for all the corner cases (like null, length checks etc). But, this direction could help.

Problem

Spring Profile annotation allows you to select profiles. However if you read documentation it only allows you to select more than one profile with OR operation. If you specify @Profile("A", "B") then your bean will be up if either profile A or profile B is active. Our use case is different we want to support TEST and PROD versions of multiple configurations. Therefore sometimes we want to autowire the bean only if both profiles TEST and CONFIG1 are active. Is there any way to do it with Spring? What would be the simplest way?

Original source