7

I want to be able to read the active profiles from a property file so that different environments (dev,prod etc) can be configured with different profiles in a Spring MVC based web application. I know that the active profiles can be set through JVM params or system properties. But I would like to do it through a property file instead. The point is that I dont know the active profile statically and instead want to read it from a properties file. It looks like this is not possible. For eg., if I had 'spring.profiles.active=dev' in application.properties, and allow it to be overridden in override.properties like so:

<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
    <property name="ignoreResourceNotFound" value="true" />
    <property name="locations">
        <list>
            <value>classpath:/application.properties</value>
            <value>file:/overrides.properties</value>
        </list>
    </property>
</bean> 

the profile is not being picked up in the environment. I guess this is because the active profiles are being checked before bean initialization, and therefore do not honor the property being set in a properties file. The only other option I see is to implement an ApplicationContextInitializer that will load those property files in order of priority(override.properties first if it exists, else application.properties) and set the value in context.getEnvironment(). Is there a better way to do it from properties files?

Navin Viswanath
  • 894
  • 2
  • 13
  • 22
  • 2
    It's usually smarter to set an O/S env var and pass it to spring. That way you can deploy one war to different servers and nothing else, and they will behave differently based on that env var value – Neil McGuigan Aug 12 '15 at 23:35
  • 1
    possible duplicate of [How to set the Profile using application.properties in Spring?](http://stackoverflow.com/questions/18614849/how-to-set-the-profile-using-application-properties-in-spring) – Bond - Java Bond Aug 13 '15 at 07:05
  • Include the code fragment to show how the profile is set with the placeholder to the propertiesconfigurer. – UserF40 Jul 25 '16 at 21:25

1 Answers1

3

One solution to do it is to read necessary property file with specified profile "manually" - without spring - and set profile at context initialization:

1) Write simple properties loader:

import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;
import java.util.Properties;

public class PropertiesLoader
{
    private static Properties props;

    public static String getActiveProfile()
    {
        if (props == null)
        {
            props = initProperties();
        }
        return props.getProperty("profile");
    }

    private static Properties initProperties()
    {
        String propertiesFile = "app.properties";
        try (Reader in = new FileReader(propertiesFile))
        {
            props = new Properties();
            props.load(in);
        }
        catch (IOException e)
        {
            System.out.println("Error while reading properties file: " + e.getMessage());
            return null;
        }
        return props;
    }
}

2) Read profile from properties file and set it during Spring container initialization (example with Java-based configuration):

public static void main(String[] args)
{
    AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
    ctx.getEnvironment().setActiveProfiles(PropertiesLoader.getActiveProfile());
    ctx.register(AppConfig.class);
    ctx.refresh();

    // you application is running ...

    ctx.close();
}
Ivan Pronin
  • 1,768
  • 16
  • 14