如何使用 Spring Boot 应用程序中另一个属性文件中的值解析属性文件中的占位符

Posted

技术标签:

【中文标题】如何使用 Spring Boot 应用程序中另一个属性文件中的值解析属性文件中的占位符【英文标题】:How to resolve placeholder in properties file with values from another properties file in spring boot application 【发布时间】:2019-07-19 20:34:02 【问题描述】:

我的 Spring Boot 应用程序具有以下属性文件。

src/main/resources/config/DEV/env.properties
mail.server=dev.mail.domain

src/main/resources/config/QA/env.properties
mail.server=qa.mail.domain

src/main/resources/config/common/env.properties
mail.url=$mail.server/endpoint

是否可以加载“common/env.properties”,以便使用给定的环境特定属性文件解析占位符。对于 DEV 环境,我们希望使用“DEV/env.properties”中的值来解析“common/env.properties”中的占位符。

有关于如何加载多个属性文件和基于配置文件加载的答案,但找不到此特定用例的答案。

提前致谢。

【问题讨论】:

这正是application.properties 和配置文件系统的用途。 【参考方案1】:

2 个选项:

    使用configuration-maven-plugin 生成common/application.properties 并为每个环境过滤文件。现在已经过时了。 为每个环境使用application-<env>.properties,并在应用程序启动时将-Dspring.profiles.active=<env> 作为VM 选项传递。 Spring 会自动从正确的文件中获取属性。

在选项 2 中,您将使用 application-.properties 覆盖 application.properties 中存在的任何内容。因此,您不必只添加每个环境需要更改的属性。

例如:

你的application.properties可以有

logging.level.root=WARN
logging.level.org.apache=WARN
logging.level.org.springframework=WARN

你的application-dev.properties可以有

logging.level.org.springframework=DEBUG

这意味着,当您使用dev 配置文件启动应用程序时,spring 需要

logging.level.root=WARN
logging.level.org.apache=WARN
logging.level.org.springframework=DEBUG

编辑:

此外,您可以在课堂上尝试以下内容。 (Spring 将使用 config-dev.properties 中的值覆盖 config.properties 中的值)。 ignoreResourceNotFound 将确保即使找不到相应的文件,应用程序仍会以默认值启动。

@Configuration
@PropertySource("classpath:config.properties")
@PropertySource(value = "classpath:config-$spring.profiles.active.properties", ignoreResourceNotFound = true)

【讨论】:

谢谢。我会试试这个并更新。出于好奇,有没有办法使用 /common/env.properties 而不是 application.properties 来存储默认值。 您可以将 env.properties 文件添加到类路径中。看看这个:***.com/questions/44499306/…【参考方案2】:

您可以添加 resources/application.yml 文件,您可以在一个文件中拥有多个配置文件。 MultiProfile Yaml 例如,这里有两个不同的配置文件 'dev' 和 'qa',具有不同的 applicationNames 'DEV' 和 'QA' 和一个 defaultName 'Default'

spring:
  application:
    name: Default
  profiles:
    active: qa

---
spring:
  profiles: dev
  application:
    name: DEV
---
spring:
  profiles: qa
  application:
    name: QA

【讨论】:

【参考方案3】:

您可以通过在类配置中声明属性源并在路径中设置环境变量来实现此目的:

@PropertySource( "classpath:config/$env/env.properties" )
@Configuration
public class config

然后你用命令行变量-env=dev启动spring boot应用程序

更新

您可以使用@PropertySources 注解来加载多个属性。

 @PropertySources(
    @PropertySource("classpath:config/$env/env.properties"),
    @PropertySource("classpath:config/common/env.properties")
  )
  public class config

【讨论】:

谢谢。 /common/env.properties 将如何加载?我们需要同时加载 /common/env.properties 和 env/env.properties。 请在答案中查看我的更新。您可以使用 @PropertySources 注释加载多个属性。因此,您可以同时加载 /common/env.properties 和 env/env.properties。如果有帮助,感谢将答案标记为回复。 谢谢,如果我们以这种方式加载,/common/env.properties 中的占位符会被 env/env.properties 中的值解析吗? 因为/common/env.properties这个路径没有占位符,所以没有解析。 不在路径中,但是/common/env.properties的内容中有占位符。例如; mail.url=$mail.server/端点。我们需要使用来自 env/env.properties 内容的值来解析 $mail.server。 /DEV/env.properties 包含 mail.server=dev.mail.domain

以上是关于如何使用 Spring Boot 应用程序中另一个属性文件中的值解析属性文件中的占位符的主要内容,如果未能解决你的问题,请参考以下文章

如何在没有spring-boot的情况下使用eureka+feign?

如何使用 Spring Boot 进行本地简单项目?

如何使用 CommandLineJobRunner 调用嵌入在 Spring Boot 应用程序中的 Spring Batch 作业

如何将基于 Spring Boot 构建的依赖项使用到典型的 Spring 应用程序中?

如何使用 Spring Boot 配置 Shiro

Spring Boot 如何极简入门?