Is your feature request related to a problem? Please describe.

Yes. It appears that @Bean definitions, marked with @RefreshScope and @ConditionalOnProperty(prefix = "something", name = "enabled", havingValue="true", matchIfMissing=true) defined in @Configuration classes are not re-evaluated or re-created when the property value changes. In other words, the act of creating a bean can only occur on startup, and the bean lifecycle is not affected by the conditional when its state is refreshed.

Related, but not quite the same, issue: https://github.com/spring-cloud/spring-cloud-config/issues/1089

Describe the solution you'd like

1

Consider:

@Configuration
@EnableConfigurationProperties(SomeConfigurationProperties.class)
@ConditionalOnProperty(name = "my.property.value")
public class SomeConfiguration {
    @Bean
    @RefreshScope
    public MyBean myBean() {
        return new MyBean();
    }
}

If I blank out my.property.value, and refresh the world, myBean should go away.

2

Consider:

@Configuration
@EnableConfigurationProperties(SomeConfigurationProperties.class)
@ConditionalOnProperty(prefix = "my.property", name = "enabled", havingValue = "true", matchIfMissing=true)
public class SomeConfiguration {
    @Bean
    @RefreshScope
    public MyBean myBean() {
        return new MyBean();
    }
}
  • If I set my.property.enabled=false, and refresh the world, myBean should go away.
  • If I set my.property.enabled=true, and refresh the world, myBean should be re-created.

3

Similar to above, consider:

@Configuration
@EnableConfigurationProperties(SomeConfigurationProperties.class)
public class SomeConfiguration {
    @Bean
    @RefreshScope
    @ConditionalOnProperty(prefix = "my.property", name = "enabled", havingValue = "true", matchIfMissing=true)
    public MyBean myBean() {
        return new MyBean();
    }
}
  • If I set my.property.enabled=false, and refresh the world, myBean should go away.
  • If I set my.property.enabled=true, and refresh the world, myBean should be re-created.

Describe alternatives you've considered

Considered removing the conditional, resorting back to if/then/else statements to return enabled/disabled versions of the bean. Feels ugly, and of course does not scale if there are N beans in the configuration class all controlled by the same property.

Additional context

  • JDK 11
  • Spring Boot 2.3.1.RELEASE
  • Spring Cloud 2.2.3.RELEASE

I am not sure if this is a bug, or the behavior is intended, etc. Based on the post here I am guessing this should be supported[?].

Comment From: spencergibb

I'm not sure this ever worked or is something that we want to support. @ConditionalOn* annotations are processed at a specific time in the application context lifecycle. With @RefreshScope, when the cache is cleared, the bean is simply re-instantiated, none of the application context lifecycle is repeated. I would suggest using the alternative you described.

Comment From: mmoayyed

I appreciate the update. Indeed this seems like a tough problem to solve. Thanks for the clarification.

Comment From: odione

This feature will help us to maintain the code design clean. It's very easy to implement 'feature toggle' with that.