I'm trying to programmatically set the .properties
file for my Spring MVC application based on the profile. For example, if the profile is dev
I'd like to source the database-dev.properties
file.
So inside my web.xml
I have it call out to my custom class
<servlet>
<servlet-name>spring-web</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
<init-param>
<param-name>contextInitializerClasses</param-name>
<param-value>com.galapagos.context.CustomEnvironmentApplicationContextInitializer</param-value>
</init-param>
</servlet>
The custom class just looks at the current profile and adds the correct .properties
file to environment's property sources
public class CustomEnvironmentApplicationContextInitializer
implements ApplicationContextInitializer<ConfigurableApplicationContext> {
private static final Logger logger = LoggerFactory.getLogger(
CustomEnvironmentApplicationContextInitializer.class);
@Override
public void initialize(ConfigurableApplicationContext applicationContext) {
// Get the environment
ConfigurableEnvironment environment = applicationContext.getEnvironment();
try {
profile = environment.getActiveProfiles()[0];
String fileName = String.format(
"database-%s.properties",
profile);
ResourcePropertySource resource =
new ResourcePropertySource(new ClassPathResource(fileName));
environment.getPropertySources().addFirst(resource);
logger.info("Loaded: " + resource);
} catch (IOException e) {
logger.warn("Error loading: " + e);
}
// Print the list of property sources
logger.info("ENVIRONMENT: " + environment.getPropertySources());
// Refresh the context - is this even needed??
applicationContext.refresh();
}
}
I can tell the above is working because it prints out the property sources at the bottom
2017-01-29 21:43:25 INFO CustomEnvironmentApplicationContextInitializer:66 - ENVIRONMENT: [class path resource [database-dev.properties],servletConfigInitParams,servletContextInitParams,jndiProperties,systemProperties,systemEnvironment]
All the database-%{xxx}.properties
files for each profile are pretty straightforward. Just some JDBC connection properties
jdbc.driverClassName=org.postgresql.Driver
jdbc.url=jdbc:postgresql://localhost:5432/galapagos
jdbc.username=my_user
jdbc.password=
And finally inside my servlet definition I load the resources and create a dataSource
<beans:bean
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
</beans:bean>
<!-- Database / JDBC -->
<beans:bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
<beans:property name="driverClassName" value="${jdbc.driverClassName}" />
<beans:property name="url" value="${jdbc.url}" />
<beans:property name="username" value="${jdbc.username}" />
<beans:property name="password" value="${jdbc.password}" />
</beans:bean>
However I'm getting a failure because it can't resolve the placeholder names
Could not resolve placeholder 'jdbc.driverClassName' in string value "${jdbc.driverClassName}"; nested exception is java.lang.IllegalArgumentException: Could not resolve placeholder 'jdbc.driverClassName' in string value "${jdbc.driverClassName}"
Looking around at various examples, they all seem to use this sort of set up (here's one). Any reason the placeholders aren't taking effect?
Thanks!