Spring Cloud Refresh 事件无法识别已删除的属性?
Posted
技术标签:
【中文标题】Spring Cloud Refresh 事件无法识别已删除的属性?【英文标题】:Spring Cloud Refresh event does not recognize removed properties? 【发布时间】:2016-12-20 07:21:05 【问题描述】:背景:
我有一个使用 Spring Cloud 运行的 Spring Boot 1.4 应用程序。我的应用程序正在使用本机配置文件从外部 config.properties 文件中提取设置。配置服务器嵌入在同一个应用程序中。
在 config.properties 文件中,我添加了以下设置:
app.setting=helloworld
什么有效:
当我更改属性并发送 REFRESH 事件时,标记的相关 bean 被重新加载并且更改被正确识别。
什么不起作用:
如果我实际上从 config.properties 中删除了该属性(例如通过将其注释掉),则 REFRESH 事件不会实际刷新应用程序。 Spring Cloud 似乎无法识别属性被删除的事实,当数据绑定器继续更新世界的状态时,它错过了属性被删除的事实,并且链接到它的相应 bean 也必须刷新并且它的字段设置为空白/空等。
看起来数据绑定器只查看配置中当前可用的内容,并没有记录过去是什么。
在 bean 配置状态中实际禁用该设置的唯一方法不是删除它,而是将其设置为一个空白值(这是一个新值,因为该设置只是一个字符串)。注意映射到该属性的 Java bean 中的字段除了 null 之外没有默认值,并且该值未在其他任何地方定义(如在嵌入式 application.properties 文件中等)
-
我可能缺少什么?
这是一项功能吗?漏洞?
感谢您的宝贵时间。
【问题讨论】:
【参考方案1】:我在刷新外部 config.properties 文件时遇到了类似的问题。这个问题体现在我的 config.properties 中,因为它只有一个 single 条目。
演示:
首先覆盖应用程序属性
application.properties
some.value=abc
config.properties
some.value=xyz
最初,使用 some.value 将呈现“xyz”
要显示该值可以更新,请更改 config.properties 中的值
config.properties
some.value=123
使用 /refresh 端点,刷新上下文,然后使用 some.value 将呈现“123”
现在,通过删除属性,我们可以看到值没有更新
config.properties
// now empty
使用 /refresh 端点刷新上下文,然后使用 some.value 将仍然呈现“123”。它没有识别出该字段已被删除,也没有使用 application.properties 中的“abc”值。
问题源于第 428 行的 ConfigFileApplicationListener 类,该类将属性文件标识为空,因此不会将文件加载到属性源中,稍后用于将新属性与 @ 中的旧属性进行比较987654322@上课。该场景似乎将旧场景留在了记忆中。
要解决此问题,当您只有一个属性时,您可以添加像 a.b 这样的属性,这将强制文件以无值加载并产生正确的功能。
config.properties
a.b=true
// item removed, but use some property to make sure it's read later
希望对你有帮助
【讨论】:
【参考方案2】:不确定这是否适用于您,但我对使用 @ConfigurationProperties
注释并使用 @EnableAutoConfiguration
注册的 bean 有类似的问题:
@ConfigurationProperties(prefix="example")
@RefreshScope
public class MyConfig
private List<String> values;
@EnableAutoConfiguration(MyConfig.class)
public class ApplicationConfiguration
我遇到的问题是您的 YAML 配置如下:
example:
- Some
- Values
- Here
当上下文被刷新时,从列表中删除项目并没有从MyConfig.values
中删除它们。
原因是使用@EnableAutoConfiguration
注册MyConfig
不允许您更改bean 的范围,这意味着刷新上下文时不会重新创建bean。见Github Issue。
我的修复
我从@EnableAutoConfiguration
中删除了MyConfig
并明确添加了@Component
注释:
@Component
@ConfigurationProperties(prefix="example")
@RefreshScope
public class MyConfig
private List<String> values;
@EnableAutoConfiguration
public class ApplicationConfiguration
此后,从 YAML 列表中删除项目会在刷新上下文时反映在 MyConfig
中。
【讨论】:
以上是关于Spring Cloud Refresh 事件无法识别已删除的属性?的主要内容,如果未能解决你的问题,请参考以下文章
在 Spring Cloud Config Client 中启用 /bus/refresh 端点
spring cloud深入学习-----配置中心svn示例和refresh
spring cloud-config的client中/refresh的端点报错401
Spring Cloud Bus 不再支持对 /actuator/bus-refresh 的 POST 请求