I'm running a PoC around replacing bean injection at runtime after a ConfigurationProperties has changed. This is based on spring boot dynamic configuration properties support as well summarised here by Dave Syer from Pivotal.
In my application I have a simple interface implemented by two different concrete classes:
@Component @RefreshScope @ConditionalOnExpression(value = "'${config.dynamic.context.country}' == 'it'") public class HelloIT implements HelloService { @Override public String sayHello() { return "Ciao dall'italia"; } } and
@Component @RefreshScope @ConditionalOnExpression(value = "'${config.dynamic.context.country}' == 'us'") public class HelloUS implements HelloService { @Override public String sayHello() { return "Hi from US"; } } application.yaml served by spring cloud config server is:
config: name: Default App dynamic: context: country: us and the related ConfigurationProperties class:
@Configuration @ConfigurationProperties (prefix = "config.dynamic") public class ContextHolder { private Map<String, String> context; Map<String, String> getContext() { return context; } public void setContext(Map<String, String> context) { this.context = context; } My client app entrypoint is:
@SpringBootApplication @RestController @RefreshScope public class App1Application { @Autowired private HelloService helloService; @RequestMapping("/hello") public String hello() { return helloService.sayHello(); } First time I browse http://locahost:8080/hello endpoint it returns "Hi from US"
After that I change country: us in country: it in application.yaml in spring config server, and then hit the actuator/refresh endpoint ( on the client app).
Second time I browse http://locahost:8080/hello it stills returns "Hi from US" instead of "ciao dall'italia" as I would expect.
Is this use case supported in spring boot 2 when using @RefreshScope? In particular I'm referring to the fact of using it along with @Conditional annotations.
@ConditionalOn*annotations are meant to be used in@Configurationclasses, not on beans directly. Configuration aren't re-run at refresh scope, just the individual beans are recreated. I would inject the@ConfigurationPropertiesinto a single bean to get the desired effect.@RefreshScopealso behaves badly on@Configurationclasses, it is meant only for individual beans.@ConfigurationProperties. Looking at my example, are you saying to inject it intoApp1Applicationbean ( which has@RefreshScopeannotation) and then using it to select the desired HelloService implementation programatically ( using for example applicationContext.getBean() ) ?Annotationwhich serve as pointcut for a customAdvicewhich, in turn, will use ConfigurationProperties (the context) for selecting at runtime different bean methods. Something similar to the @Flip annotation used by ff4j feature flag framework