I'm trying to port our Custom Properties Placeholder with Spring's new Environment
support but I can't figure out how to get what our current placeholder magic does.
What I would like is for a default bunch of property files to be read from classpath and then have those properties overridden (overlay) by a bunch of properties files from somewhere else. I don't want all of the properties replaced just the ones that are set in the other group of files.
Prior to Spring 3.1
<bean class="com.snaphop.spring.ConfigResourcesFactoryBean" id="customConfig">
<property name="parameterName" value="customConfig"/>
<property name="defaultResources" value="classpath*:META-INF/spring/*.properties"/>
</bean>
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer" id="customPropertyPlaceholder">
<property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE"/>
<property name="locations" ref="customConfig"/>
</bean>
Now ConfigResourcesFactoryBean is just a magically FactoryBean that finds the list of resources to feed to the placeholder config:
public class ConfigResourcesFactoryBean implements FactoryBean<Resource[]> {
// Loads a bunch of Resources (property files)
// based on System.property/Environment variable "customConfig"
}
Now customConfig might be set like -DcustomConfig=file://blah/*.properties
or export customConfig=file://blah/*.properties
.
The properties in the directory blah
only override a subset of the classpath*:META-INF/spring/*.properties
. Thus the returned Resource[]
from the factory will be a union of classpath*:META-INF/spring*.properties
followed by file://blah/*.properties
respectively.
Now it appears instead of my Resource[]
factory I can make a custom PropertySources
and wire that into the PlaceholderConfig but that seems like it offers no value then the above.
I cannot use ApplicationContextInitializer
because I swear that only works with Servlet environments and thus will not work with integration tests (I don't feel like adding an annotation on every single one of my unit tests to go tell it what the environment is when I could just set a system property like I did before).
How does one overlay properties from hardcoded sources with custom sources with out having to overriding/implementing a bunch of classes?