简体   繁体   中英

Override properties from external property file if exists using Spring

I have the following property file defined in one of my Spring configuration file:

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

Now I want to override few properties from some external property file that is not in the classpath.

Let's say I have my project deployed somewhere and I need to some dynamic configuration change. I do not want to make updates to the project codebase in the container(tomcat or any thing).

1.) So I need a way that updates (overrides) the values of spring's loaded properties file with my recent updates in the external property file.

2.) It would be great if somebody could also share the way to refresh the properties that are preloaded.

So I need a way that updates (overrides) the values of spring's loaded properties file with my recent updates in the external property file.

You can use the PropertyPlaceholderConfigurer .

Either this way If you want to use the context namespace

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

or this way

<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>

According to the javadoc of PropertiesLoaderSupport.setLocations(Resource[])

... Note: Properties defined in later files will override properties defined earlier files, in case of overlapping keys. Hence, make sure that the most specific files are the last ones in the given list of locations.

.

It would be great if somebody could also share the way to refresh the properties that are preloaded.

At the moment you are using a PropertyPlaceholderConfigurer . Since a PropertyPlaceholderConfigurer is a BeanFactoryPostProcessor it traverses the bean definitions (object representation of the beans.xml ) and replaces the property strings (such as ${someProp}). After that the beans get instantiated and initialized. Thus there is no way to 'reload' the properties.

There is even more to consider if you want to build an application that can react to property changes at runtime:

  • How can you trigger the change at Runtime? Eg a timer that polls a property file for changes, JMX, ...?
  • How are classes that depend on properties are informed about the update? Eg a listener implementation.
  • How do I synchronize the updates of many dependent properties? Eg imagine what will happen if properties get updated during a web app request without synchronization. A part of the request might use the old and another the new properties.

At least I would recommend to use apache commons configuration . But it is only a framework that solves a few problems and you still have to think about solutions to the questions above.

in spring boot 2, it is

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

You can get full details in https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-external-config.html

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM