java - 在 Spring Boot 应用程序中添加条件外部 PropertySource
问题描述
我目前正在使用 EnvironmentPostProcessor 添加我的外部 PropertySource,代码如下所示:
public class ExternalPropertySourceEnvironmentPostProcessor implements EnvironmentPostProcessor
{
private static final String EXTERNAL_PROPERTY_SOURCE_NAME = "ExternalPropertySource";
@Override
public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application)
{
if (environment.acceptsProfiles(Profiles.EXTERNAL_PROPERTY_SOURCE_ENABLED_PROFILE)) {
environment.getPropertySources()
.addLast(new ExternalPropertySource(EXTERNAL_PROPERTY_SOURCE_NAME, new ExternalSource()));
}
}
}
spring.factories 也用于注册这个 EnvironmentPostProcessor。
如果在 vm 环境变量中设置了配置文件,则此代码实际上可以工作,但如果将其添加到 src/main/resources/application.yml 中,则配置文件似乎尚未注入环境中,并且不会被environment.getActiveProfiles()。我尝试过使用优先级最低的 Ordered 接口,但它没有帮助。
为了围绕我要实现的目标添加一些上下文,该类位于一个小型库中,该库添加了一个外部属性源,例如数据库。然后我们可以在其他一些 Spring Boot 应用程序中使用它。像 Spring Cloud Config 这样的东西。
我想要一种干净的方法来启用或禁用此属性源,具体取决于代码运行的环境。我不介意使用其他东西然后配置文件甚至另一种方式来注入属性源,我只想要一些不依赖于几个因素的干净的东西。
我现在代码中的主要问题是我正在使用Spring Boot 的属性源来使我自己的属性源可配置。
更新:我使用了一个 Spring Cloud 应用程序来调试它,并且将引导上下文与正常的 Spring 引导上下文混淆了。请看下面我的回答。
解决方案
进一步调查使我发现问题仅出现在 Spring Cloud 应用程序中。
事实上,我在这段代码中的断点被触发了两次,一次是在引导上下文初始化之后,一次是在弹簧引导上下文初始化之后。我只是在第一次出现时调试配置文件。此时,仅加载 bootstrap.yml 属性,而不加载 application.yml 文件中的属性。第二次出现显然有我的 application.yml 文件中的配置文件。
我的代码在一个普通的 Spring Boot 应用程序中按预期工作。正如文档所述:
环境已经准备好 Spring Boot 默认加载的所有常用属性源。
我对我的应用程序的行为感到困惑,这似乎与该声明不同,但 Spring Cloud 的引导程序扰乱了我的调试。
由于我需要一个具有最高优先级的 PropertySource,因此我需要在 Spring Cloud 应用程序的引导后初始化中添加它。我在 EnvironmentPostProcessor 上使用了一个 init 标志,因此它不会被执行两次,并在 Spring Cloud 应用程序上使用 bootstrap.yml 来设置配置文件。
TL;DR: 使用 Spring Cloud,EnvironmentPostProcessor 会被调用两次:一次在引导初始化之后,一次在正常的 Spring Boot 上下文初始化之后。如果您需要注入属性并且针对 Spring Cloud 的后引导初始化,请使用 bootstrap.yml 而不是 application.yml。
推荐阅读
- javascript - 我的网站在较小的设备上没有响应
- xquery - 使用 MarkLogic Java API 与 QConsole 的通配符搜索无法按预期工作
- tensorflow - 为什么当我使用 numpy 数学时 GradientTape 返回 None
- django - GET Body 没有与 APIClient Django DRF 一起发送
- php - php 在尝试回显时不会从 url 中获取值
- python - 如何重构函数以在列表中仅返回 1 个 True 值?
- x86 - 哈斯韦尔和继任者还能掩盖 A20 线吗?
- hyperledger-sawtooth - 事务提交到sawtooth intkey TP没有响应
- php - 如何让第三个盒子在第一个盒子下面而不是在中间?
- vb.net - For F 处预期的表达式