How to use Spring Profiles – Tutorial with Examples

Introduction to Spring Profiles – Learn Spring and Spring Boot Profiles to set environment-specific configurations with the help of real-life examples.

What is Spring Profile?

Spring Profiles help segregate application configurations to inject environment-specific configurations without changing the application.

The Spring profile is a group of variables and configurations in a Spring application that we can plugin during the application startup. Having this, we can deploy the same application in different environments without making any changes.

We can define the profile-specific configurations in Spring’s application properties or YAML files. @Configuration classes, or @Bean factory methods. Having the profile-specific configurations, we can inject a specific profile during an application startup using an environment variable or JVM system property. In the following sections, we will go through the examples of each of the ways.

Why Do We Need Spring Profiles?

Spring Profiles helps to set the right configurations on the right environments easily.

An application connects to different external resources – for example, databases, messaging systems or external services. These external services’ connection details and credentials are environment specific and may change over time. In addition, an application’s settings and configurations change with the environment.

Thus, we should isolate these configurations into Spring’s @Configuration class, properties files or YAML files. With Spring profiles, we can have different versions of such @Configuration classes and properties or YAML files. That makes the configurations easy to manage and maintain.

Without Spring profiles, we will have to write factory-like components to make certain things available based on certain environment-specific parameters.

Spring @Profile Annotation

The @Profile is Spring’s annotation that we can use on a class or a method, indicating that the class or method is eligible for registration when a particular profile or more is active.

@Profile on a Class: We can use @Profile annotation on a class that bears @Configuration or @Component annotation directly or indirectly.

@Profile on a Method: We can use @Profile on a @Bean method.

Using @Profile on @Configuration class

When we use @Profile annotation on a @Configuration class, Spring loads that configuration only when the given profiles are active.

The following snippet shows a @Configuration class that registers only in a specific environment or profile – ‘prod‘.

@Configuration
@Profile("prod")
public class ApplicationConfig {
    // Skipped Configurations
}Code language: Java (java)

We may have a @Configuration class that applies to more than one environment. In that case, we can specify multiple profiles using @Profile annotation.

@Configuration
@Profile({"dev", "prod"})
public class ApplicationConfig {
    // Skipped Configurations
}Code language: Java (java)

The @Profile annotation supports Spring Expression Language (SpEL), and we can write more complex expressions. For example, the following snippet uses a negation expression to register the @Configuration class in all but one environment or profile.

@Configuration
@Profile("!test")
public class ApplicationConfig {
    // Skipped Configurations
}Code language: Java (java)

Using @Profile on @Bean Methods

The @Bean methods are factory methods for Spring-managed bean instances. We can use @Profile annotation on such factory methods to map factory methods to specific profiles.

Consider a scenario where an application uses different Database providers in different environments. In the following snippet, there are two @Bean methods to create a Datasource instance – Oracle data source and MySQL data source.

We can use @Profile annotation on the @Bean methods to map them 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;
}Code language: Java (java)

Using @Profile on @Component Classes

Similarly, we can use the @Profile annotation directly on the Spring Bean class that has one of the Spring stereotype annotations. Using @Profile on a @Component class, we can map interface implementations to specific profiles.

@Profile("prod")
@Component
public class SQSMessageListener implements MessageListener {
  // implementation skipped
}Code language: PHP (php)
@Profile("dev")
@Component
public class JMSMessageListener implements MessageListener {
  // implementation skipped
}Code language: PHP (php)

Spring Boot Profile-Specific Properties and YAML Files

Spring Boot has inbuilt support for the environment or profile-specific Application Properties or YAML files. That means we can have multiple application properties or YAML files, and Spring will refer to the file that applies to the currently active profile.

The default properties file in a Spring Boot application is ‘application.properties‘. In addition, we can have profile-specific properties that follow the naming pattern – ‘application-{spring.profiles.active}.properties‘.

Spring Boot finds a particular property in the default properties file if it is unavailable in the profile-specific properties files.

To understand it better, refer to the following environment-specific properties files.

application.properties

spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.username=db-userCode language: Properties (properties)

The default properties or YAML files can contain common configurations across environments.

Only the configurations that are environment-specific go into their respective properties files.

application-dev.properties

spring.datasource.url=jdbc:mysql://dev_db_host:3306/app-db
spring.datasource.password=<password>Code language: Properties (properties)

application-prod.properties

spring.datasource.url= jdbc:mysql://prod_host:3306/app-db
spring.datasource.password=<password>Code language: Properties (properties)

Consider the Spring Active Profile is set to ‘dev‘, and Spring refers to the ‘application-dev.properties‘ file. Because of the fallback mechanism, Spring refers to the URL and the Password from the environment-specific file and the rest from the default properties file.

Profile in XML Bean Configurations

We can map Spring beans to profiles using the ‘profile‘ attribute for a more traditional Spring application that uses XML-based configurations.

<beans profile="dev">
    <bean id="configuration" class="com.amitph.spring.DevConfigurations" />
    ... 
    <!-- more beans -->
</beans>Code language: HTML, XML (xml)

How to set Spring Active Profiles?

We learned how to create Spring active profile-specific configurations and beans in the previous sections. We will now discuss how to activate Spring Active Profiles.

One of the most convenient ways of setting an Active Spring Profile is by using the ‘spring.profiles.active’ variable. We can set it from a command line argument, environment variable, or a programmatic approach.

Set Spring Active Profiles with an Environment Variable

One of the quickest ways to set a Spring Active Profile is to set an environment variable. Following is how we can set Spring Active Profiles in a Unix-based environment.

~ export spring_profiles_active="prod"Code language: Bash (bash)

We can leverage this during containerised deployments where the CI/CD pipelines can inject the environment variables at a run time, allowing us to deploy the same image in different environments.

Set Spring Active Profiles as JVM System Property

Alternatively, we can also set the Spring Boot Active Profile as a JVM System Property. To do that, we can pass the profile as an argument to the application startup command.

~ java -jar -Dspring.profiles.active=prod my-service.jarCode language: Bash (bash)

Set Spring Active Profile Programmatically

This is a programmatic way of setting up an active profile.

@Configuration
public class InitConfigurations 
    implements WebApplicationInitializer {

  @Override
  public void onStartup(ServletContext servletContext) 
      throws ServletException {
    
    // Skipped other initializations
    servletContext.setInitParameter("spring.profiles.active", "prod");
  }
}Code language: Java (java)

Set Spring Active Profile using Properties or YAML file

We can also activate a specific Spring Profile using the default Application Properties or YAML file. As discussed earlier, if a profile-specific properties file or a particular property is missing, Spring refers to the default properties file.

application.properties

spring.profiles.active=devCode language: Properties (properties)

application.yaml

spring:
  profiles:
    active: devCode language: YAML (yaml)

Thus, if Spring Profiles active is not already set, by any other means, Spring will refer to this configuration.

Summary

This article gave a detailed overview of using Spring Active Profiles and configuring the active profiles.

We had a detailed overview of Spring Profiles and learned how to use Spring’s @Profile annotation to create profile-specific spring beans and configurations. Then we understood how the profile-specific Application Properties or YAML files help us maintain environment-specific configurations. Lastly, we discussed different ways in which we can activate Spring Boot Active profiles.