2020-04-23

Spring environment configuration for dev, qa, staging, prod

Spring Boot is aware of Spring profiles, as well. Profiles are a mechanism that lets you tag objects and property files so that they can be selectively activated or deactivated at runtime. This is great if you want to have an environment-specific configuration. You can tag a Spring bean or a configuration file as belonging to a particular profile, and Spring will automatically load it for you when that profile is activated.

Profile names are, basically, arbitrary. Some profiles are magic - that Spring honors in a particular way. The most interesting of these is default, which is activated when no other profile is active. But generally, the names are up to you. I find it very useful to map my profiles to different environments: dev, qa, staging, prod, etc.

Let’s say that there’s a profile called dev. Spring Boot will automatically load application-dev.properties. It’ll load that in addition to applicatin.properties. If there are any conflicts between values in the two files, then the more specific file - the one with the profile - wins. You could have a default value that applies absent a particular profile, and then provide specifics in the config for a profile.

You can activate a given profile in several different ways, but the easiest is just to specify it on the command line. Or you could turn it on in your IDE’s run configurations dialog box. IntelliJ and Spring Tool Suite both provide a place to specify the profile to sue when running the application. You can also set an env var, SPRING_PROFILES_ACTIVE, or specify an argument on the command line --spring.profiles.active. Either one accepts a comma-delimited list of profiles - you can activate more than one profile at a time.

Le’ts try that out. Create a file called application-dev.properties. Put the following value in it.

message-from-application-properties=Hello from dev application.properties

This property has the same key like the one in application.properties. The java code here is identical to what we had before. Just be sure to specify the profile before you start the Spring application. You can use the environment variable, properties, etc. You can even define it programmatically when building the SpringApplication in the main() method.

package com.example.configuration.profiles;

import lombok.extern.log4j.Log4j2;
import org.springframework.boot.ApplicationRunner;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.core.env.Environment;

@Log4j2
@SpringBootApplication
public class ConfigurationApplication {

    public static void main(String[] args) {
        // this works
        // export SPRING_PROFILES_ACTIVE=dev 
        // System.setProperty("spring.profiles.active", "dev"); // so does this
        new SpringApplicationBuilder()
            .profiles("dev") // and so does this
            .sources(ConfigurationApplication.class)
            .run(args);
    }

    @Bean
    ApplicationRunner applicationRunner(Environment environment) {
        return args -> {
            log.info("message from application.properties " + environment.getProperty("message-from-application-properties"));
        };
    }
}
Run the application, and you’ll see the specialized message reflected in the output.

No comments:

Post a Comment