Java Spring Boot:在没有Spring Cloud配置服务器的情况下重新加载配置 [英] Java Spring Boot: Reload config without spring cloud config server

查看:144
本文介绍了Java Spring Boot:在没有Spring Cloud配置服务器的情况下重新加载配置的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试在运行时重新加载应用程序的配置.配置位于yaml文件中,并且与@ConfigurationProperties的绑定按预期进行.接下来是. yaml更改后,我想重新加载配置.或者更确切地说,我正在用@Scheduled检查文件是否已更改.

I am trying to reload configuration of my application during runtime. The configuration is in a yaml file and the binding with @ConfigurationProperties works as expected. Next thing is. I want to reload the config when the yaml has changed. Or rather I am checking with @Scheduled whether the file has changed.

我想避免因为我的Environment更新而运行第二台服务器.我有两个问题:

I would like to avoid running a second server for having my Environment update. The two questions I have:

  1. 如何更新环境,也许ConfigurableEnvironment?
  2. 我该如何传播这些东西?

Spring云配置文档说明:

Spring cloud config documentation states:

EnvironmentChangeEvent涵盖了一大类刷新用例,只要您实际上可以更改Environment并发布事件(这些API是公共的,并且是Spring核心的一部分)

The EnvironmentChangeEvent covers a large class of refresh use cases, as long as you can actually make a change to the Environment and publish the event (those APIs are public and part of core Spring)

因此,发布事件是可行的,但是我不了解如何实际更新属性.

So publishing the Event is working, but I do not get on how to actually update the properties.

推荐答案

对此进行了很多讨论:如何在不使用任何配置服务器的情况下刷新属性.在此处上有一个Dave Syer帖子,它带来了一些启示-但仍然不是我自己-不言而喻.

There is quite a discussion on that: how to refresh properties without any configuration server. There is a Dave Syer post on that here which brings some light - but still isn't self-explanatory.

随后将是spring-boot/-cloud的最自然方法(如

The most natural approach for spring-boot/-cloud would be following (as discussed on spring-cloud-config github):

@Component
@ConfigurationProperties("ignored")
@RefreshScope
public class Config {
    private List<String> path;

    public List<String> getPath() {
        return path;
    }

    public void setPath(List<String> path) {
        this.path = path;
    }
}

由于@RefreshScope@ConfigurationProperties之间的某些代理问题,此方法不起作用-两种注释都导致Bean代理之间的相互矛盾.

This doesn't work due to some proxy issues between @RefreshScope and @ConfigurationProperties - both annotations result in bean proxies with are at odds with each other.

因此,我从春天的角度开始研究它. propertySources可通过Environment访问,因此您可以通过以下方式访问和修改它们:

Therefore I started looking at it from a spring perspective. The propertySources are accessible through Environment so you can access and modify them by

final String propertySourceName = "externalConfiguration"; 
// name of propertySource as defined by 
// @PropertySource(name = "externalConfiguration", value = "${application.config.location}")
ResourcePropertySource propertySource = new ResourcePropertySource(propertySourceName, new FileSystemResource(file));
MutablePropertySources sources = ctx.getEnvironment().getPropertySources();
sources.replace(propertySourceName, propertySource);

我的用例基于用户编辑文件",因此刷新的属性基于FileSystemWatcher,后者使propertySources发生了变化.为了使配置Bean正确提取源,该Bean的范围需要是一个原型-在每次调用时都要正确地重建.

My use case was based on "user editing the file" so the properties refreshed was based on the FileSystemWatcher, which mutated the propertySources. For the sources to be correctly ingested by the configuration bean, the scope of the bean needed to be a prototype - to be correctly rebuilt on every invocation.

完整的示例是可用作要旨.不包含任何配置服务器.希望有帮助

The complete example is available as a gist. No config server is included whatsoever. Hope that helps

这篇关于Java Spring Boot:在没有Spring Cloud配置服务器的情况下重新加载配置的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆