5

背景:

我有一个使用 Spring Cloud 运行的 Spring Boot 1.4 应用程序。我的应用程序正在使用本机配置文件从外部 config.properties 文件中提取设置。配置服务器嵌入在同一个应用程序中。

在 config.properties 文件中,我添加了以下设置:

app.setting=helloworld

什么有效:

当我更改属性并发送 REFRESH 事件时,标记的相关 bean 被重新加载并且更改被正确识别。

什么不起作用:

如果我实际上从 config.properties 中删除了该属性(例如通过将其注释掉),则 REFRESH 事件实际上不会刷新应用程序。Spring Cloud 似乎没有认识到属性被删除的事实,当数据绑定器继续更新世界的状态时,它错过了属性被删除的事实,并且链接到它的相应 bean 也必须刷新并且它的字段设置为空白/空等。

看起来 data-binder 只查看配置中当前可用的内容,而不记录what is 与 what is

在 bean 配置状态中实际禁用该设置的唯一方法不是删除它,而是将其设置为一个空白值(这是一个新值,因为该设置只是一个字符串)。请注意,映射到此属性的 Java bean 中的字段除了 null 之外没有默认值,并且该值未在其他任何地方定义(如在嵌入式 application.properties 文件等中)

  1. 我可能会错过什么?
  2. 这是一个功能吗?漏洞?

谢谢你的时间。

4

2 回答 2

3

不确定这是否适用于您,但我对使用注释@ConfigurationProperties和注册的 bean 有类似的问题@EnableAutoConfiguration

@ConfigurationProperties(prefix="example")
@RefreshScope
public class MyConfig {
    private List<String> values;
}

@EnableAutoConfiguration(MyConfig.class)
public class ApplicationConfiguration {
}

我遇到的问题是当你有一个 YAML 配置时:

example:
  - Some
  - Values
  - Here

从列表中删除项目并不会MyConfig.values在刷新上下文时将它们删除。

原因是注册MyConfigusing@EnableAutoConfiguration不允许您更改 bean 的范围,这意味着刷新上下文时不会重新创建 bean。请参阅Github 问题

我的修复

MyConfig我从中删除@EnableAutoConfiguration并明确添加了一个@Component注释:

@Component
@ConfigurationProperties(prefix="example")
@RefreshScope
public class MyConfig {
    private List<String> values;
}

@EnableAutoConfiguration
public class ApplicationConfiguration {
}

MyConfig在此之后,从 YAML 列表中删除项目会在刷新上下文时反映出来。

于 2017-01-12T03:34:17.460 回答
2

刷新外部 config.properties 文件时,我遇到了类似的问题。这个问题体现在我的 config.properties 中,因为它只有一个条目

展示:

首先覆盖应用程序属性

应用程序属性

some.value=abc

配置属性

some.value=xyz

最初,使用 some.value 将呈现“xyz”

要显示该值可以更新,请更改 config.properties 中的值

配置属性

some.value=123

使用 /refresh 端点,刷新上下文,然后使用 some.value 将呈现“123”

现在,通过删除属性,我们可以看到值没有更新

配置属性

// now empty

使用 /refresh 端点,刷新上下文,然后使用 some.value 仍将呈现“123”。它没有认识到该字段已被删除,也没有使用 application.properties 中的“abc”值。

问题源于ConfigFileApplicationListener类,该类在第 428 行将属性文件标识为空,因此不会将文件加载到属性源中,这些属性源稍后用于比较ContextRefresher类中的新属性与旧属性。该场景似乎将旧场景保留在内存中。

要解决此问题,当您只有一个属性时,您可以添加诸如 ab 之类的属性,这将强制以无值加载文件并产生正确的功能。

配置属性

a.b=true
// item removed, but use some property to make sure it's read later

希望这可以帮助

于 2017-03-06T21:30:51.000 回答