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

2022-09-01 13:13:25

我在我的一个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

...注: 在键重叠的情况下,在更高版本中定义的属性将覆盖早期文件中定义的属性。因此,请确保最具体的文件是给定位置列表中的最后一个文件。

.

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

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

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

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

至少我建议使用apache commons配置。但它只是一个解决几个问题的框架,你仍然需要考虑上述问题的解决方案。


答案 2

在弹簧靴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 中获取完整的详细信息