For @ConditionalOnProperty, It cannot express a property does not exist or not equal to specific value, we could introduce a boolean attribute like negated to revert the matching result to achieve this. @ConditionalOnProperty(value = "foo", negated = true) to match property foo does not exist. @ConditionalOnProperty(value = "foo", havingValue = "bar", negated = true) to match property foo is not equal to bar.

It applies to others like @ConditionalOnClass also.

I would like to prepare PR if the team accepts.

Comment From: bclozel

I think we shouldn't make this condition more complex than it is already - a SpEL expression would be easier to understand and read in this case. Also a custom annotation with NoneNestedConditions would be probably a better fit.

Comment From: snicoll

The issue tracker has several of those requests that have been declined already, see https://github.com/spring-projects/spring-boot/issues/23794

Comment From: quaff

The issue tracker has several of those requests that have been declined already, see #23794

This proposal is not just for @ConditionalOnProperty, my idea is introducing a new base condition:

public abstract class NegatableSpringBootCondition<T extends Annotation> extends SpringBootCondition {

    public static final String NEGATED_ATTRIBUTE_NAME = "negated";

    @Override
    public final boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
        boolean result = super.matches(context, metadata);
        Class<?> clazz = ResolvableType.forClass(getClass()).as(NegatableSpringBootCondition.class).getGeneric().resolve();
        Assert.state(clazz != null, "Generic of NegatableSpringBootCondition should be present");
        Map<String, Object> annotationAttributes = metadata.getAnnotationAttributes(clazz.getName());
        if (annotationAttributes != null && annotationAttributes.containsKey(NEGATED_ATTRIBUTE_NAME)) {
            if ((Boolean) annotationAttributes.get(NEGATED_ATTRIBUTE_NAME)) {
                result = !result;
            }
        }
        return result;
    }

}

then let On*Condition extends NegatableSpringBootCondition<ConditionalOnProperty> instead of SpringBootCondition, and add boolean negated attribute to corresponding annotation.

Comment From: quaff

Proof of concept: https://github.com/spring-projects/spring-boot/compare/main...quaff:spring-boot:patch-53

Comment From: goughy000

The issue tracker has several of those requests that have been declined already, see #23794

@snicoll the fact it's been requested several times suggests it's something the community would find useful?

Comment From: snicoll

@snicoll the fact it's been requested several times suggests it's something the community would find useful?

I am not denying that. Please take the time to follow the link I've shared as it provides more context as to why this was declined.

Comment From: goughy000

@snicoll I've read the linked issue as well as the others linked off it and the reasonings provided all seem to be

  • specific to one use case being used as a reason that this will not be useful to anyone
  • suggesting alternatives such as nested negated conditions or writing spel which are more complicated to read and more likely to get wrong

No worries though, I've added my own annotation in our codebase that we can use. Thanks for your consideration and I understand it's not wanted in core

Comment From: philwebb

I think the discussion in #4938 is also relevant to this issue. I'm afraid my opinion hasn't really changed since https://github.com/spring-projects/spring-boot/issues/4938#issuecomment-189052999 and I don't think we should be adding any more complexity to this condition, especially as we haven't yet found a need for it ourselves.

Thanks anyway for the suggestion and prototype code @quaff!

Comment From: quaff

I think the discussion in #4938 is also relevant to this issue. I'm afraid my opinion hasn't really changed since #4938 (comment) and I don't think we should be adding any more complexity to this condition, especially as we haven't yet found a need for it ourselves.

Thanks anyway for the suggestion and prototype code @quaff!

Detecting missing properties is not much useful, but it make sense to check a property is NOT equal to specific value, maybe we should repurpose to fix it.

Comment From: philwebb

I still feel like we'd be adding more complexity to the condition than we'd like. I'd prefer that we recommend NoneNestedConditions unless we find a really really compelling use-case for updating the condition.