Spring Profiles

Spring Profiles helps segregating your application configurations, and make them available only in certain environments. 

Profiles are a core feature of the framework — allowing us to map our beans to different profiles — for example, dev, test, and prod.

We can then activate different profiles in different environments to bootstrap only the beans we need.

An application run on many different environments. For example, Dev, QA, Test, Stage, Production etc. Therefore, an application may need different configurations on different environments.. In other words, configurations like databases, messaging systems, server ports, security will be different from environment to environment.

Spring Profiles helps to easily set right configurations on right environments. Otherwise, without having Spring Profiles it is a big pain to manage environment specific configurations. For example, your application may have to rely on the configurations externalised on the environments. Obviously, that is fairly difficult to keep in-sync. Otherwise, you will have to write bunch of factory like components to make certain things available based on certain environment specific parameters parameters.

Using @Profile on Configuration Class

Let’s have a look at the three Configuration classes below. The DefaultConfigurations doesn’t have any Profile configured. Therefore, it will be available on all environments. However, the other configurations will be available only the specific active profiles.

@Configuration

public class DefaultConfigurations {

    // Skipped Configurations

}

@Configuration

@Profile("dev")

public class DevConfigurations {

    // Skipped Configurations

}

@Configuration

@Profile("prod")

public class ProdConfigurations {

    // Skipped Configurations

}


Using @Profile on @Bean Methods

Spring Profiles are not limited to deployment environments. In other words, It can be used to bring any variation in application profile.

For example, consider your application has oracle and mysql profiles and you need to create different datasources. Now below is the way to have two different datasources tied up to specific profiles.


@Bean

@Profile("oracle")

public DataSource oracleDataSource(){

    DataSource dataSource;

    // implementation skipped

    return dataSource;

}

@Bean

@Profile("mysql")

public DataSource mySqlDataSource(){

    DataSource dataSource;

    // implementation skipped

    return dataSource;

}

How to set Active Profiles

By now, you know how to make use of Spring Profiles for injecting various configurations. In this section you will learn how to start an application in a specific Profile.

Environment Variable

Set up an environment variable spring_profiles_active.

~ export spring_profiles_active="mySql"

Programatically during Application Init

This is a programatic way of setting up active profile.

@Configuration

public class InitConfigurations implements WebApplicationInitializer {

    @Override

    public void onStartup(ServletContext servletContext) throws ServletException {

        // Skipped other initialisations


        servletContext.setInitParameter("spring.profiles.active", "mySql");

    }

}

Spring Boot Active Profiles

The Spring Boot supports @Profie annotations on the configurations and as well as Bean Methods. In addition, Spring Boot supports environment specific properties files. Because of these properties files properties management becomes really easy.

Spring Boot Environment Specific Properties

For example, you can declare properties files like application-propduction.properties or application-production.properties.

Application properties naming scheme: application-{spring_active_profile}.properties.

Once, you have a set of environment specific properties files, Spring Boot picks up the one that matches the current active profile. Spring Boot finds a key in default properties file if it is not available in the profile specific properties files. The default properties file is represented as application.properties.

For example, take a look at three different properties file below

application.properties

spring.profiles.active=dev

spring.datasource.driver-class-name= com.mysql.jdbc.Driver

spring.datasource.username= songs_service_user

Code language: Properties (properties)


application-dev.properties

spring.datasource.url= jdbc:mysql://dev_db_host:3306/songsDB

spring.datasource.password= <password>

Code language: Properties (properties)


application-prod.properties

spring.datasource.url= jdbc:mysql://prod_host:3306/songsDB

spring.datasource.password= <password>


These are simple datasource related properties. The default properties has common things like driver and database username. Moreover, Spring Boot reads the default properties file in all profiles. The other two files contains environment specific properties, such as database url and database password.

The default properties file has an additional entry spring.profiles.active=dev. If you don’t set active profile anywhere else, Spring Boot will use this. Note, this setting has the the lease priority.

Spring Boot Active Profiles Command Line Argument

Before we end, it is interesting to know that the Environment variable can override application level active profile. Alternatively, you can also set the active profile as command line arguments.

For example, when you run Spring Boot application as a JAR, you can pass the Active profile as command line argument.

~ java -jar -Dspring.profiles.active=prod song-service.jar


Comments

Popular posts from this blog

Java 8 : Find the number starts with 1 from a list of integers

Junit Mockito and Power Mockito

Customized Immutable Class