Spring 在引导配置之间共享属性

Spring 在引导配置之间共享属性,spring,spring-boot,spring-cloud,Spring,Spring Boot,Spring Cloud,问题: 我有两个库,它们的目的是从各自的源中获取属性,并在启动时将它们提供给我的应用程序。目前,这两个库都提供了自己的属性SourceLocators,作为其BootstrapConfiguration的一部分 (如本文所述) 例如 libraryX负责从SourceX获取属性并配置相应的PropertySourceLocator Library负责从SourceY获取属性并配置相应的PropertySourceLocator 这些库在mybootstrap.yaml中配置。例如 lib

问题:

我有两个库,它们的目的是从各自的源中获取属性,并在启动时将它们提供给我的应用程序。目前,这两个库都提供了自己的
属性SourceLocator
s,作为其
BootstrapConfiguration
的一部分

(如本文所述)

例如

  • libraryX负责从SourceX获取属性并配置相应的PropertySourceLocator

  • Library负责从SourceY获取属性并配置相应的PropertySourceLocator

这些库在my
bootstrap.yaml
中配置。例如

libX.enabled: true
libX.password: ${LIB_X_PASS}

libY.enabled: true
libY.password: ${LIB_Y_PASS}
只要这些库不使用彼此的属性,一切都可以正常工作

不幸的是,在我的例子中,libX应该是${LIB_Y_PASS}的源

因此,
bootstrap.yaml
现在看起来像这样:

libX.enabled: true
libX.password: ${LIB_X_PASS}

libY.enabled: true
libY.password: ${libX.values.lib_y_pass}
在此配置中,由于${LIB_X_PASS}和${libX.values.LIB_y_PASS}的解析发生在调用
PropertySourceLocator
s之前,因此应用程序不再启动

潜在解决方案:

  • 使用
    @PropertySource
    而不是
    libX
    上的
    PropertySourceLocator
  • @PropertySource
    s提供的值似乎在
    bootstrap.yaml
    中的属性解析发生时可用。唯一的问题是,它似乎与项目中的其他
    应用程序*.yaml
    /
    应用程序*.properties
    文件具有相同的优先级。因此,不可能用来自
    libX
    的内容覆盖现有属性。 例如

    libY.password
    将具有
    dummy\u password
    值,而不是来自
    libX
    @PropertySource
    的值。可能的原因是,
    bootstrap.yaml
    as propertySource出现在创建的属性源libX之前,在解析过程中,spring从拥有它的第一个propertySource中选取值

  • 使用
    org.springframework.boot.env.EnvironmentPostProcessor
  • 我们可以在环境后处理阶段将libX属性源作为第一个属性源注入。 例如

    这似乎很好,并从解决方案1中解决了问题,但我不知道是否有我尚未发现的隐藏问题

    问题

    有没有更好的方法来解决这个问题

    这似乎是: A) 我的案例(当我需要从一个引导
    PropertySourceLocator
    到另一个引导
    PropertySourceLocator
    的属性时)违背了
    PropertySourceLocator
    的设计,在这种情况下,像这样的黑客攻击是唯一的方法。
    B) 我遗漏了一些东西,这个问题可以用一种更简单的方式解决。

    这是bootstrap的一个限制。这将随着boot 2.4.0配置文件处理的变化而变化,因为环境将是累积的。嘿,斯宾塞·吉布。谢谢你的评论。我曾尝试使用2020.0.0-M4 spring云版本重新实现相同的示例,但它似乎存在相同的问题。您能解释一下,为了使它与这个新版本的库一起工作,需要做哪些更改吗?这是github中的同一个示例,恐怕它比堆栈覆盖流答案更深入。它不使用bootstrap或PropertySourceLocator,而是使用新的spring boot
    ConfigData
    API
    libX.enabled: true
    libX.password: ${LIB_X_PASS}
    
    libY.enabled: true
    libY.password: ${libX.values.lib_y_pass}
    libX.values.lib_y_pass: dummy_password
    
    @Override
    public void postProcessEnvironment(ConfigurableEnvironment environment,
                                       SpringApplication application) {
    
        ....
        environment.getPropertySources().addFirst(libxPropertySource);
    }