在 Spring 中使用 System 覆盖属性

Posted

技术标签:

【中文标题】在 Spring 中使用 System 覆盖属性【英文标题】:Overriding properties with System in Spring 【发布时间】:2014-04-22 19:02:18 【问题描述】:

我开发了一个将在 AWS BeanStalk 上运行的 REST WS。

目前,数据源配置了属性文件:

database.driverClass=org.postgresql.Driver
database.jdbcUrl=jdbc:postgresql://localhost:5432/public
database.username=postgres
database.password=postgres

在 context.xml 中:

<bean id="dataSource" class="com.jolbox.bonecp.BoneCPDataSource" destroy-method="close">
    <property name="driverClass" value="$database.driverClass" />
    <property name="jdbcUrl" value="$database.jdbcUrl"/>
....

但是现在,我需要一个使用 AWS Beanstalk 的 preprod 环境来公开我的系统属性,例如 RDS_HOSTNAME、RDS_PORT、RDS_DB_NAME、...

有没有办法保持相同的系统,比如写作

database.jdbcUrl=jdbc:postgresql://#RDS_HOSTNAME:#RDS_PORT/#RDS_DB_NAME

在 preprod.property 中?

或者用 context.xml 中的系统属性重置 database.jdbcUrl?

【问题讨论】:

在命令行上设置属性有用吗? 您使用什么构建工具?编写脚本以根据输出目标生成自定义属性文件非常简单。 @mttdbrd :我更喜欢有一个单一的战争来加载他的上下文依赖于 spring.profiles.active。 @chrylis :我看到你的评论和 mttdbrd 的评论,我忘了说这是一个 webapp :p 是的,我是说你为 Maven 设定了一个目标,比如“preprod”,它会自动创建正确的属性文件并将其填充到单个战争中。如果使用得当,单个构建工具可以生成具有正确 .properties 的正确 war 文件,用于 test、local、preprod、prod 等。 【参考方案1】:

你可以的

   <context:property-placeholder ignore-unresolvable="true" ignore-resource-not-found="true" location="classpath:database.properties, file:preProd.properties" />

preProd.properties 将在 preprod 机器上。键将相同,但值将不同。这样,如果 preProd.properties 未找到(例如在开发机器上),将使用 database.properties。如果文件 preProd.properties 存在,它将覆盖 database.properties 中的值。

如果你使用 maven,你也可以使用 maven profile 和 maven-replacer-plugin。

【讨论】:

Maven 似乎是去这里的方式。不确定 OP 是否正在使用它,但这是 Maven 旨在解决的问题。我相信你可以用 Gradle 做同样的事情,但我不知道怎么做。 它不适用,因为目标是部署在 beanstalk 上,这会创建一个 RDS 并为我们提供系统属性。 ops 只想部署一个没有任何构建系统的 war 文件。 他们是如何获得战争文件的?您必须进行某种构建才能达到这一点。我所说的只是在一切都打包之前进行干预。

以上是关于在 Spring 中使用 System 覆盖属性的主要内容,如果未能解决你的问题,请参考以下文章

使用 Spring 覆盖外部属性文件中的属性(如果存在)

使用spring覆盖属性文件

用本地属性覆盖远程 Spring Cloud 属性

通过环境变量覆盖 Spring Boot yaml 属性

spring cloud config如何使用本地属性覆盖远程属性

无法将配置文件夹中 logback-spring.xml 的属性覆盖到其他模块的 logback-spring.xml