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

Posted

技术标签:

【中文标题】使用 Spring 覆盖外部属性文件中的属性(如果存在)【英文标题】:Override properties from external property file if exists using Spring 【发布时间】:2014-01-27 17:05:26 【问题描述】:

我的 Spring 配置文件之一中定义了以下属性文件:

<context:property-placeholder location="classpath:project.properties"/> 

现在我想覆盖一些不在类路径中的外部属性文件中的一些属性。

假设我的项目部署在某个地方,我需要进行一些动态配置更改。我不想更新容器(tomcat 或任何东西)中的项目代码库。

1.) 所以我需要一种方法,用我最近在外部属性文件中的更新来更新(覆盖)spring 加载的属性文件的值。

2.) 如果有人也可以分享刷新预加载属性的方法,那就太好了。

【问题讨论】:

【参考方案1】:

所以我需要一种方法,用我最近在外部属性文件中的更新来更新(覆盖)spring 加载的属性文件的值。

您可以使用PropertyPlaceholderConfigurer。

如果你想使用context命名空间

<context:property-placeholder location="classpath:yourClasspath.properties,file:/some/resource/path/filePropertiesToOverride.properites"/> 

或者这样

<bean id="placeholderConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
    <property name="locations">
        <list>
            <value>classpath:yourClasspath.properties</value>
            <value>file:/some/resource/path/filePropertiesToOverride.properites</value>
        </list>
    </property>
</bean>

根据PropertiesLoaderSupport.setLocations(Resource[])的javadoc

... 注意:在后面的文件中定义的属性将覆盖早期文件中定义的属性,以防重叠键。因此,请确保最具体的文件是给定位置列表中的最后一个。

.

如果有人也可以分享刷新预加载属性的方法,那就太好了。

目前您使用的是PropertyPlaceholderConfigurer。由于PropertyPlaceholderConfigurerBeanFactoryPostProcessor,它遍历bean 定义(beans.xml 的对象表示)并替换属性字符串(例如$someProp)。之后,bean 被实例化和初始化。因此无法“重新加载”属性。

如果您想构建一个可以在运行时对属性更改做出反应的应用程序,还有更多需要考虑的因素:

如何在运行时触发更改?例如。轮询属性文件以进行更改、JMX、...的计时器? 如何将更新通知依赖于属性的类?例如。监听器实现。 如何同步多个依赖属性的更新?例如。想象一下,如果在没有同步的 Web 应用请求期间更新属性会发生什么。请求的一部分可能使用旧属性,另一部分使用新属性。

至少我会推荐使用apache commons configuration。但它只是一个解决了几个问题的框架,对于上面的问题,你仍然需要思考解决方案。

【讨论】:

如果我对外部属性文件进行更改,属性将如何即时刷新? @SaurabParakh 动态更改属性是一项很大的工作,因为需要考虑很多事情。我更新了我的答案,希望它可以帮助你做出决定。 @RenéLink 是一种可能带有注释和环境变量的解决方案? TIA【参考方案2】:

在spring boot 2中是

java -jar myproject.jar --spring.config.location=classpath:/default.properties,classpath:/override.properties

您可以在https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-external-config.html获得完整的详细信息

【讨论】:

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

“当前目录”中的 Spring Boot 外部属性文件被忽略

Maven 配置文件属性不会覆盖弹簧配置中的值

查看当前 Spring (Boot) 属性

无法从 Spring Boot 中的外部属性文件中读取值

使用spring覆盖属性文件

Spring ConditionalOnProperty 用于外部属性