I want to conditionally apply one properties file based on the values specified in another properties file. application.properties is meant to modified by deployers and specifies the dbType like so:
Then I have properties files that define specific properties per database type, like oracle.properties:
Code:
hibernate.dialect=net.sf.hibernate.dialect.OracleDialect
or mssqlserver.properties:
Code:
hibernate.dialect=net.sf.hibernate.dialect.SQLServerDialect
Those properties are not included in application.properties because they are not meant to be modified by deployers and we don't want Hibernate-specific settings to be exposed.
I want to conditionally include one of the db-specific files based on the dbType value at run-time. If dbType is oracle, include oracle.properties; if dbType is mssqlserver, mssqlserver.properties, etc. I set up my bean definitions like this:
Code:
<bean id="appProperties" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location"><value>application.properties</value></property>
</bean>
<bean id="hibernateProperties" class="org.springframework.beans.factory.config.PropertyOverrideConfigurer">
<property name="location"><value>${dbType}.properties</value></property>
</bean>
That doesn't work the way I expected it to; the resource loader in PropertyOverrideConfigurer attempts to load a file named "${dbType}.properties", not "oracle.properties".
The reason for this is in the method invokeBeanFactoryPostProcessors() in AbstractApplicationContext. It queries the internal bean factory for all beans of type BeanFactoryPostProcessor. The first post-processor (appProperties) runs and and correctly sets the value of the property "location" on the bean definition for "hibernateProperties" to be "oracle.properties". Then it attempts to run the second post-processor ("hibernateProperties"), but which results in a Fil. That is because the post-processor bean was instantiated before the property value was modified by the first post-processor ("appProperties").
As a result, I cannot have a PropertyResourceConfigurer that has values set by another PropertyResourceConfigurer (either PropertyPlaceholderConfigurer or PropertyOverrideConfigurer). I investigated modifying invokeBeanFactoryPostProcessors() in AbstractApplicationContext, but any changes to the bean definition would require a full bean factory refresh to appear, which doesn't seem like a good thing. Suggestions? Thanks.