通过 Spring 启动程序包括配置文件
Including profiles via a Spring Boot starter
我在使用自定义 Spring 引导程序时遇到问题。启动器如何导致包含配置文件并从配置服务器中提取相关配置?
也许我的用例是独一无二的,因为我没有在网上找到任何有用的信息。我在企业环境中工作,这个启动器供我的团队使用,因此我们能够控制一些在开源世界中可能没有意义的东西(比如配置文件名称)。
场景如下:我们有一个 Spring 云配置服务器 运行 提供配置。在我们的 Spring 启动项目中,我们对某些配置文件名称进行了标准化,例如 "prod" 和 "nonprod" 以控制我们不同环境中的配置。我正在尝试创建一个 starter 来提供可重用的功能。出于示例目的,假设我正在创建一个启动器,它为为我们执行加密工作的设备提供接口。此启动器将需要设备的 IP 地址以及生产和非生产之间不同的各种其他配置。
在配置存储库中,我将拥有 application.yml、application-nonprod.yml、application-nonprodEncryption.yml 等文件
我的目标是让自定义加密启动器在应用程序中包含该启动器时自动包含 nonprodEncryption 配置文件。通过这样做,不需要加密的应用程序不会加载加密相关的属性。
到目前为止,这是我的实验结果:
在应用程序的 bootstrap.yml 中,我可以放置一个块,例如
spring.profiles: nonprod
spring:
profiles:
include:
- nonprodEncryption
并产生了预期的结果(即 application-nonprodEncryption.yml 文件从配置服务器加载并使用),但这是一个不受欢迎的解决方案,因为每个使用我的自定义启动器的应用程序都需要包含这个样板配置。
当我把上面的配置移到starter的bootstrap.yml时,好像没有效果
当我将上面的配置移动到启动器的 application.yml 时,它似乎被应用了(即它出现在 The following profiles are active:
列表中),但为时已晚在生命周期中导致从配置服务器中提取适当的配置。
我考虑过的其他事项:
为什么不将所有配置放入主配置文件配置文件(例如 application-nonprod.yml)?从关注点和维护的角度来看,我想将各个启动器的配置彼此隔离。此外,一些配置数据比其他配置数据更敏感,所以我不喜欢将所有配置公开给所有应用程序的想法,因为许多应用程序不需要一些更敏感的配置。是的,他们可以得到它,但如果他们不需要它,为什么要把它加载到他们的记忆中呢?
为什么不在我们启动应用程序时指定额外的配置文件?这些应用程序将 运行 在云平台上。该平台将根据应用程序所在的层 运行 指定 "prod" 或 "nonprod" 作为配置文件。我想在平台级别而不是应用程序级别管理它,所以我希望在应用程序启动时提供的配置文件列表在所有应用程序中保持一致(例如,向列表中添加 nonprodEncryption 只会让我陷入与上述相同的情况 - 所有应用程序都将具有所有配置,所以我也可以只需将它们全部放在一个文件中即可)。
我们目前正在使用 Spring Boot 1.5.10。
关于如何实现我想要做的事情有什么想法吗?
我终于找到了解决方案(以防其他人发现自己在同一个地方)。
第 1 步:将这样的配置 class 添加到您的启动器:
package com.company.bootstrap;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Profile;
@Configuration
@Profile("nonprod")
public class BootstrapNonprod {
public BootstrapNonprod(ConfigurableApplicationContext ctx) {
ctx.getEnvironment().addActiveProfile("nonprodEncryption");
}
}
这将有条件地添加配置文件。在此示例中,每当 "nonprod" 配置文件处于活动状态时,此 class 将添加 "nonprodEncryption" 配置文件。
第 2 步:在初学者的 spring.factories 文件中,添加如下一行:
org.springframework.cloud.bootstrap.BootstrapConfiguration=com.company.bootstrap.BootstrapNonprod
好像就是这么简单
我在使用自定义 Spring 引导程序时遇到问题。启动器如何导致包含配置文件并从配置服务器中提取相关配置?
也许我的用例是独一无二的,因为我没有在网上找到任何有用的信息。我在企业环境中工作,这个启动器供我的团队使用,因此我们能够控制一些在开源世界中可能没有意义的东西(比如配置文件名称)。
场景如下:我们有一个 Spring 云配置服务器 运行 提供配置。在我们的 Spring 启动项目中,我们对某些配置文件名称进行了标准化,例如 "prod" 和 "nonprod" 以控制我们不同环境中的配置。我正在尝试创建一个 starter 来提供可重用的功能。出于示例目的,假设我正在创建一个启动器,它为为我们执行加密工作的设备提供接口。此启动器将需要设备的 IP 地址以及生产和非生产之间不同的各种其他配置。
在配置存储库中,我将拥有 application.yml、application-nonprod.yml、application-nonprodEncryption.yml 等文件
我的目标是让自定义加密启动器在应用程序中包含该启动器时自动包含 nonprodEncryption 配置文件。通过这样做,不需要加密的应用程序不会加载加密相关的属性。
到目前为止,这是我的实验结果:
在应用程序的 bootstrap.yml 中,我可以放置一个块,例如
spring.profiles: nonprod spring: profiles: include: - nonprodEncryption
并产生了预期的结果(即 application-nonprodEncryption.yml 文件从配置服务器加载并使用),但这是一个不受欢迎的解决方案,因为每个使用我的自定义启动器的应用程序都需要包含这个样板配置。
当我把上面的配置移到starter的bootstrap.yml时,好像没有效果
当我将上面的配置移动到启动器的 application.yml 时,它似乎被应用了(即它出现在
The following profiles are active:
列表中),但为时已晚在生命周期中导致从配置服务器中提取适当的配置。
我考虑过的其他事项:
为什么不将所有配置放入主配置文件配置文件(例如 application-nonprod.yml)?从关注点和维护的角度来看,我想将各个启动器的配置彼此隔离。此外,一些配置数据比其他配置数据更敏感,所以我不喜欢将所有配置公开给所有应用程序的想法,因为许多应用程序不需要一些更敏感的配置。是的,他们可以得到它,但如果他们不需要它,为什么要把它加载到他们的记忆中呢?
为什么不在我们启动应用程序时指定额外的配置文件?这些应用程序将 运行 在云平台上。该平台将根据应用程序所在的层 运行 指定 "prod" 或 "nonprod" 作为配置文件。我想在平台级别而不是应用程序级别管理它,所以我希望在应用程序启动时提供的配置文件列表在所有应用程序中保持一致(例如,向列表中添加 nonprodEncryption 只会让我陷入与上述相同的情况 - 所有应用程序都将具有所有配置,所以我也可以只需将它们全部放在一个文件中即可)。
我们目前正在使用 Spring Boot 1.5.10。
关于如何实现我想要做的事情有什么想法吗?
我终于找到了解决方案(以防其他人发现自己在同一个地方)。
第 1 步:将这样的配置 class 添加到您的启动器:
package com.company.bootstrap;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Profile;
@Configuration
@Profile("nonprod")
public class BootstrapNonprod {
public BootstrapNonprod(ConfigurableApplicationContext ctx) {
ctx.getEnvironment().addActiveProfile("nonprodEncryption");
}
}
这将有条件地添加配置文件。在此示例中,每当 "nonprod" 配置文件处于活动状态时,此 class 将添加 "nonprodEncryption" 配置文件。
第 2 步:在初学者的 spring.factories 文件中,添加如下一行:
org.springframework.cloud.bootstrap.BootstrapConfiguration=com.company.bootstrap.BootstrapNonprod
好像就是这么简单