Reputation: 93
How to configure PropertySourcesPlaceholderConfigurer with custom .properties files for different environments (production, dev, staging)? on deploy spring throws "Could not resolve placeholder 'property.placeholder' in string value "classpath:${property.placeholder}" "
here is my pom.xml
<profiles>
<profile>
<id>dev</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<property.placeholder>_developer.properties</property.placeholder>
</properties>
</profile>
<profile>
<id>staging</id>
<activation>
<activeByDefault>false</activeByDefault>
</activation>
<properties>
<property.placeholder>_staging.properties</property.placeholder>
</properties>
</profile>
<profile>
<id>production</id>
<activation>
<activeByDefault>false</activeByDefault>
</activation>
<properties>
<property.placeholder>_production.properties</property.placeholder>
</properties>
</profile>
</profiles>
here is PropertySourcesPlaceholderConfigurer configuration
static @Bean
public PropertySourcesPlaceholderConfigurer myPropertySourcesPlaceholderConfigurer() {
PropertySourcesPlaceholderConfigurer p = new PropertySourcesPlaceholderConfigurer();
org.springframework.core.io.Resource[] resourceLocations = new org.springframework.core.io.Resource[] {
new ClassPathResource("${property.placeholder}")
};
p.setLocations(resourceLocations);
return p;
}
it works in xml spring configuration but didn't work if I use java config. Have any idea how make it works?
Upvotes: 3
Views: 2052
Reputation: 93
I found another way to do what i want:
At first I add this plugin to builds section in my pom.xml:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>properties-maven-plugin</artifactId>
<version>1.0-alpha-2</version>
<executions>
<execution>
<id>1</id>
<phase>initialize</phase>
<goals>
<goal>read-project-properties</goal>
</goals>
<configuration>
<files>
<file>src/main/resources/${property.placeholder}</file>
</files>
</configuration>
</execution>
<execution>
<id>2</id>
<phase>generate-resources</phase>
<goals>
<goal>write-project-properties</goal>
</goals>
<configuration>
<outputFile>
${project.build.outputDirectory}/application.properties
</outputFile>
</configuration>
</execution>
</executions>
</plugin>
At second I modify PropertySourcesPlaceholder configuration in my spring config file:
static @Bean
public PropertySourcesPlaceholderConfigurer myPropertySourcesPlaceholderConfigurer() {
PropertySourcesPlaceholderConfigurer p
= new PropertySourcesPlaceholderConfigurer();
org.springframework.core.io.Resource[] resourceLocations
= new org.springframework.core.io.Resource[] {
new ClassPathResource("application.properties")
};
p.setLocations(resourceLocations);
return p;
}
And also I add this annotation to my spring config class:
@PropertySource("classpath:application.properties")
So now I write env-dependent properties to different properties files (like "_developer.properties" or "_staging.properties") and when I build project with maven it has been copied to "application.properties", which I use in PropertySourcesPlaceholder configuration
Upvotes: 1
Reputation: 46851
Use System.getProperty()
to get the environment variable.
Sample code:
Environment env = new Environment(new ClassResourceLocator(ClassUtils.getDefaultClassLoader()), System.getProperty("env"));
Create PropertySourcesPlaceholderConfigurer
Bean:
@Bean
public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer()
{
PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer = new PropertySourcesPlaceholderConfigurer();
propertySourcesPlaceholderConfigurer.setPropertySources(new MyPropertySources());
return propertySourcesPlaceholderConfigurer;
}
MyPropertySources.java
public class MyPropertySources implements PropertySources{
private List<PropertySource<?>> sources = new ArrayList<>();
public EnvironmentPropertySources()
{
Environment env = new Environment(new ClassResourceLocator(ClassUtils.getDefaultClassLoader()), System.getProperty("env"));
PropertySource<?> source = ...;
// create class that extends PropertySource<String> and get property values from Environment
sources.add(source);
}
@Override
public Iterator<PropertySource<?>> iterator() {
return sources.iterator();
}
@Override
public boolean contains(String name) {
return true;
}
@Override
public PropertySource<?> get(String name) {
return sources.get(0);
}
}
Upvotes: 0