【发布时间】:2019-01-31 03:48:59
【问题描述】:
在 ConfigurationProperties 更改后,我正在运行一个 PoC,以在运行时替换 bean 注入。这是基于 Spring Boot 动态配置属性支持以及来自 Pivotal 的 Dave Syer 总结的 here。
在我的应用程序中,我有一个由两个不同的具体类实现的简单接口:
@Component
@RefreshScope
@ConditionalOnExpression(value = "'${config.dynamic.context.country}' == 'it'")
public class HelloIT implements HelloService {
@Override
public String sayHello() {
return "Ciao dall'italia";
}
}
和
@Component
@RefreshScope
@ConditionalOnExpression(value = "'${config.dynamic.context.country}' == 'us'")
public class HelloUS implements HelloService {
@Override
public String sayHello() {
return "Hi from US";
}
}
spring cloud config server服务的application.yaml是:
config:
name: Default App
dynamic:
context:
country: us
以及相关的 ConfigurationProperties 类:
@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;
}
我的客户端应用入口点是:
@SpringBootApplication
@RestController
@RefreshScope
public class App1Application {
@Autowired
private HelloService helloService;
@RequestMapping("/hello")
public String hello() {
return helloService.sayHello();
}
我第一次浏览 http://locahost:8080/hello 端点时,它返回“Hi from US”
之后,我在 spring 配置服务器的 application.yaml 中将 country: it 中的 country: us 更改为 actuator/refresh 端点(在客户端应用程序上)。
我第二次浏览 http://locahost:8080/hello 时,它仍然返回“Hi from US”,而不是我预期的“ciao dall'italia”。
使用@RefreshScope 时,Spring Boot 2 是否支持此用例?特别是我指的是与@Conditional 注释一起使用它的事实。
【问题讨论】:
-
相关开放的 GitHub 问题:github.com/spring-cloud/spring-cloud-config/issues/1089 和 SO 问题:stackoverflow.com/questions/46271052/…
-
@ConditionalOn*注解用于@Configuration类,而不是直接用于bean。配置不会在刷新范围内重新运行,只会重新创建单个 bean。我会将@ConfigurationProperties注入单个bean 以获得所需的效果。@RefreshScope在@Configuration类上也表现不佳,它仅适用于单个 bean。 -
@spencergibb 我不确定我是否理解注入
@ConfigurationProperties会获得相同的效果。查看我的示例,您是说将其注入App1Applicationbean(具有@RefreshScope注释),然后使用它以编程方式选择所需的 HelloService 实现(例如使用 applicationContext.getBean() )? -
刷新范围不能改变加载哪个bean,它只能重新初始化一个bean
-
@spencergibb 好的,所以很明显这是在运行时根据配置更改替换 spring bean 实现的错误路径。这个 PoC 的目的是在运行时根据上下文变化选择业务逻辑。我想我将研究创建一个自定义
Annotation作为自定义Advice的切入点,而Advice反过来将使用ConfigurationProperties(上下文)在运行时选择不同的bean 方法。类似于ff4j 功能标志框架使用的@Flip 注释
标签: java spring spring-boot spring-cloud