Skip to content

@ConditionalOnProperty meta annotation with @AliasFor does not work #24968

@gebezs

Description

@gebezs

The @ConditionalOnProperty is available as meta annotation (despite the #13996) but the @AliasFor does not work.

I've included a simple test showing four different bean: no condition, direct @ConditionalOnProperty, meta without alias, and meta with alias. As you can see the meta with alias does not disable the bean while the simple meta does.

My use case would be to create a @ConditionalOnModuleState meta alias with @AliasFor which could ensure that the autoconfiguration (which is loaded by spring.factories) can be turned off without removing the dependency.

package support;

import static org.assertj.core.api.Assertions.assertThatCode;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.AliasFor;
import org.springframework.test.context.TestPropertySource;

@SpringBootTest(classes = ConditionalOnPropertyTest.Config.class)
@TestPropertySource(properties = "module.enabled=false")
public class ConditionalOnPropertyTest {
  @Autowired
  private ApplicationContext context;

  @Test
  public void testReference() {
    assertThatCode(() -> context.getBean("reference"))
        .doesNotThrowAnyException();
  }

  @Test
  public void testDirect() {
    assertThatCode(() -> context.getBean("direct"))
        .isInstanceOf(NoSuchBeanDefinitionException.class);
  }

  @Test
  public void testModuleState() {
    assertThatCode(() -> context.getBean("moduleState"))
        .isInstanceOf(NoSuchBeanDefinitionException.class);
  }

  @Test
  public void testModuleStateWithAlias() {
    assertThatCode(() -> context.getBean("moduleStateWithAlias"))
        .doesNotThrowAnyException();
        // This should raise the exception too but the @AliasFor seems to be not working.
        //.isInstanceOf(NoSuchBeanDefinitionException.class);
  }

  @Configuration
  public static class Config {
    @Bean
    public Object reference() {
      return new Object();
    }

    @Bean
    @ConditionalOnProperty(prefix = "module", name = "enabled", havingValue = "true", matchIfMissing = true)
    public Object direct() {
      return new Object();
    }

    @Bean
    @ConditionalOnModuleState
    public Object moduleState() {
      return new Object();
    }

    @Bean
    @ConditionalOnModuleStateWithAlias("module")
    public Object moduleStateWithAlias() {
      return new Object();
    }
  }

  @Retention(RetentionPolicy.RUNTIME)
  @Target({ElementType.TYPE, ElementType.METHOD})
  @ConditionalOnProperty(name = "enabled", havingValue = "true", matchIfMissing = true, prefix = "module")
  public @interface ConditionalOnModuleState {
  }

  @Retention(RetentionPolicy.RUNTIME)
  @Target({ElementType.TYPE, ElementType.METHOD})
  @ConditionalOnProperty(name = "enabled", havingValue = "true", matchIfMissing = true)
  public @interface ConditionalOnModuleStateWithAlias {
    @AliasFor(annotation = ConditionalOnProperty.class, attribute = "prefix")
    String value();
  }
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    status: supersededAn issue that has been superseded by anothertype: bugA general bug

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions