Different property variable for Local and prod Environment (Spring)

spring, spring-mvc

Solution

You can load properties based on the current spring profile or profiles. To set a spring profile I mostly set a system property named `spring.profiles.active` to the desired value e.g. `development` or `production`.

The concept is pretty simple. Read the currently active profile from the system property. Build the filename and load the properties file using a `PropertySourcesPlaceholderConfigurer`. Using the `PropertySourcesPlaceholderConfigurer` will make it easier the access those properties through `@Value` annotations. Note that this examples assumes one profile is active. It may need some extra care when multiple profiles are active.

Java based configuration

@Configuration
public class MyApplicationConfiguration {

    @Bean
    public static PropertySourcesPlaceholderConfigurer propertyPlaceholderConfigurer() {
        String activeProfile = System.getProperty("spring.profiles.active", "production");
        String propertiesFilename = "app-" + activeProfile + ".properties";

        PropertySourcesPlaceholderConfigurer configurer = new PropertySourcesPlaceholderConfigurer();
        configurer.setLocation(new ClassPathResource(propertiesFilename));

        return configurer;
    }
}

You could also import multiple configuration classes annotated with `@Profile`. Spring would select which configuration to use based on the currently active profiles. Every class could add it's own version of `PropertySourcesPlaceholderConfigurer` to the application context.

@Configuration
@Import({Development.class, Production.class})
public class MyApplicationConfiguration {}

@Configuration
@Profile("development")
public class Development {}

@Configuration
@Profile // The default
public class Production {}

As Emerson Farrugia stated in his comment the `@Profile` per class approach is a bit drastic for selecting a `PropertySourcesPlaceholderConfigurer`. Annotating a `@Bean` declaration would be much simpler.

@Configuration
public class MyApplicationConfiguration {

    @Bean
    @Profile("development")
    public static PropertySourcesPlaceholderConfigurer developmentPropertyPlaceholderConfigurer() {
        // instantiate and return configurer...
    }

    @Bean
    @Profile // The default
    public static PropertySourcesPlaceholderConfigurer propertyPlaceholderConfigurer() {
        // instantiate and return configurer...
    }
}

Problem

I am working on an Spring web application in where I need to have variable's that will have different value in local environment and other value in production environment. For Eg (file upload directory). My file upload directory is different for local and prod environment. Currently I am doing it by checking the host name (if 'localhost' then A else B) and taking this approach. By there is another way to solve this problem via property files, Does anybody provide me pointers to how to approach that?

Original source