I just announced the new Spring Boot 2 material, coming in REST With Spring:

>> CHECK OUT THE COURSE

1. Overview

In this article, we’ll illustrate how to use Profiles in Spring.

As of Spring 3.1, we can now map our beans to different profiles – for example, dev, test, prod.

We can then activate different profiles in different environments to bootstrap just the beans we need:

2. Use @Profile on a Bean

Let’s start simple and look at how we can make a bean belong to a particular profile. Using the @Profile annotation – we are mapping the bean to that particular profile; the annotation simply takes the names of one (or multiple) profiles.

Consider a basic scenario – we have a bean that should only be active during development, but not deployed in production. We annotate that bean with a “dev” profile, and it will only be present in the container during development – in production, the dev simply won’t be active:

@Component
@Profile("dev")
public class DevDatasourceConfig

As a quick sidenote, profile names can also be prefixed with a NOT operator e.g. “!dev” to exclude them from a profile.

In the below example, the component is activated only if “dev” profile is not active:

@Component
@Profile("!dev")
public class DevDatasourceConfig

3. Declare Profiles in XML

Profiles can also be configured in XML – the <beans> tag has “profiles” attribute which takes comma separated values of the applicable profiles:

<beans profile="dev">
    <bean id="devDatasourceConfig" 
      class="org.baeldung.profiles.DevDatasourceConfig" />
</beans>

4. Set Profiles

The next step is to activate and set the profiles so that the respective beans are registered in the container.

This can be done in a variety of ways – which we’ll explore in the following sections.

4.1. Programmatically via WebApplicationInitializer interface

In web applications, WebApplicationInitializer can be used to configure the ServletContext programmatically.

It’s also a very handy location to set our active profiles programmatically:

@Configuration
public class MyWebApplicationInitializer 
  implements WebApplicationInitializer {

    @Override
    public void onStartup(ServletContext servletContext) throws ServletException {
 
        servletContext.setInitParameter(
          "spring.profiles.active", "dev");
    }
}

4.2. Programmatically via ConfigurableEnvironment

You can also set profiles directly on the environment:

@Autowired
private ConfigurableEnvironment env;
...
env.setActiveProfiles("someProfile");

4.3. Context Parameter in web.xml

Similarly, profiles can be activated in the web.xml of the web application as well, using a context parameter:

<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>/WEB-INF/app-config.xml</param-value>
</context-param>
<context-param>
    <param-name>spring.profiles.active</param-name>
    <param-value>dev</param-value>
</context-param>

4.4. JVM System Parameter

The profile names can also be passed in via a JVM system parameter. The profile names passed as the parameter will be activated during application start-up:

-Dspring.profiles.active=dev

4.5. Environment Variable

In a Unix environment, profiles can also be activated via the environment variable:

export spring_profiles_active=dev

4.6. Maven Profile

Spring profiles can also be activated via Maven profiles, by specifying the spring.profiles.active configuration property.

In every Maven profile, we can set a spring.profiles.active property:

<profiles>
    <profile>
        <id>dev</id>
        <activation>
            <activeByDefault>true</activeByDefault>
        </activation>
        <properties>
            <spring.profiles.active>dev</spring.profiles.active>
        </properties>
    </profile>
    <profile>
        <id>prod</id>
        <properties>
            <spring.profiles.active>prod</spring.profiles.active>
        </properties>
    </profile>
</profiles>

Its value will be used to replace the @[email protected] placeholder in application.properties:

[email protected]@

Now, we need to enable resource filtering in pom.xml:

<build>
    <resources>
        <resource>
            <directory>src/main/resources</directory>
            <filtering>true</filtering>
        </resource>
    </resources>
    ...
</build>

And append a -P parameter to switch which Maven profile will be applied:

mvn clean package -Pprod

This command will package the application for prod profile. It also applies the spring.profiles.active value ‘prod’ for this application when it is running.

4.7. @ActiveProfile in Tests

Tests make it very easy to specify what profiles are active – using the @ActiveProfile annotation to enable specific profiles:

@ActiveProfiles("dev")

To summarize, we looked at multiple ways of activating profiles. Let’s now see which one has priority over the other and what happens if you use more than one – from highest to lowest priority:

  1. Context parameter in web.xml
  2. WebApplicationInitializer
  3. JVM System parameter
  4. Environment variable
  5. Maven profile

5. The Default Profile

Any bean that does not specify a profile belongs to “default” profile.

Spring also provides a way to set the default profile when no other profile is active – by using the “spring.profiles.default” property.

6. Get Active Profiles

Once the profiles are activated, we can retrieve the active profiles at runtime, by just injecting the Environment:

public class ProfileManager {
    @Autowired
    Environment environment;

    public void getActiveProfiles() {
        for (final String profileName : environment.getActiveProfiles()) {
            System.out.println("Currently active profile - " + profileName);
        }   
    }
}

7. Example of Using Profiles

Now that the basics are out of the way, let’s take a look at a real example.

Consider a scenario where we have to maintain the datasource configuration for both the development and production environments. Let’s create a common interface DatasourceConfig that needs to be implemented by both data source implementations:

public interface DatasourceConfig {
    public void setup();
}

Following is the configuration for development environment:

@Component
@Profile("dev")
public class DevDatasourceConfig implements DatasourceConfig {
    @Override
    public void setup() {
        System.out.println("Setting up datasource for DEV environment. ");
    }
}

And configuration for the production environment:

@Component
@Profile("production")
public class ProductionDatasourceConfig implements DatasourceConfig {
    @Override
    public void setup() {
       System.out.println("Setting up datasource for PRODUCTION environment. ");
    }
}

Now let’s create a test and inject our DatasourceConfig interface; depending on the active profile, Spring will inject DevDatasourceConfig or ProductionDatasourceConfig bean:

public class SpringProfilesTest {
    @Autowired
    DatasourceConfig datasourceConfig;

    public void setupDatasource() {
        datasourceConfig.setup();
    }
}

When the “dev” profile is active spring injects DevDatasourceConfig object, and on call of setup() method following is the output:

Setting up datasource for DEV environment.

8. Profiles in Spring Boot

Spring Boot supports all the profile configuration outlined so far, with a few additional features.

The initialization parameter spring.profiles.active, introduced in section 4, can also be set up as a property in Spring Boot to define currently active profiles. This is a standard property that Spring Boot will pick up automatically:

spring.profiles.active=dev

To set profiles programmatically, we can also use the SpringApplication class:

SpringApplication.setAdditionalProfiles("dev");

To set profiles using Maven in Spring Boot, we can specify profile names under spring-boot-maven-plugin in pom.xml:

<plugins>
    <plugin>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-maven-plugin</artifactId>
        <configuration>
            <profiles>
                <profile>dev</profile>
            </profiles>
        </configuration>
    </plugin>
    ...
</plugins>

And execute the Spring Boot specific Maven goal:

mvn spring-boot:run

But the most important profiles-related feature that Spring Boot brings is profile-specific properties files. These have to be named in the format applications-{profile}.properties.

Spring Boot will automatically load the properties in an application.properties file for all profiles, and the ones in profile-specific .properties files only for the specified profile.

For example, we can configure different data sources for dev and production profiles by using two files named application-dev.properties and application-production.properties:

In the application-production.properties file, we can set up a MySql data source:

spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/db
spring.datasource.username=root
spring.datasource.password=root

Then, we can configure the same properties for the dev profile in the application-dev.properties file, to use an in-memory H2 database:

spring.datasource.driver-class-name=org.h2.Driver
spring.datasource.url=jdbc:h2:mem:db;DB_CLOSE_DELAY=-1
spring.datasource.username=sa
spring.datasource.password=sa

In this way, we can easily provide different configurations for different environments.

9. Conclusion

In this quick tutorial, we discussed how to define a profile on a bean and how to then enable the right profiles in our application.

Finally, we validated our understanding of profiles with a simple but still real-world example.

The implementation of this Spring Security REST Tutorial can be found in the GitHub project – this is a Maven-based project, so it should be easy to import and run as it is.

I just announced the new Spring Boot 2 material, coming in REST With Spring:

>> CHECK OUT THE LESSONS

newest oldest most voted
Arghya Sadhu
Guest
Arghya Sadhu

Is’nt there a way to set profiles programatically as well?

Eugen Paraschiv
Guest

Yes there is – I added a subsection in the article – hope it helps. Cheers,
Eugen.

Alexei Ptitchkin
Guest
Alexei Ptitchkin

Many thanks for this post.
Would you please enlight two questions
Is there way to load database when test profile is active?
Is it possible load not only in-memory database, mysql perhaps?

Eugen Paraschiv
Guest

Hey Alexei – profiles are a low level construct you can use in many ways. So – if you make sure you have the correct beans belonging to – for example – a “production” profile that set up your persistence for production, and then similar beans, belonging to a “test” profile – yes, you can do that. Now – there’s a much easier way to make sure your system uses one database for testing and another in production – without using profiles. You can simply have 2 different properties files: persistence-prod.properties and persistence-test.properties and load them up based on a… Read more »

Lucky
Guest
Lucky

I’m using Spring Boot. How about the priority of application.properties, application.yml etc are loaded for profile lookup?

Eugen Paraschiv
Guest

Hey Lucky – yes, Boot does have support for profiles via properties. That’s actually a good topic to add to the article as a subsection – I’ll put that on the Content Calendar.
Cheers,
Eugen.

Vijay Mareddy
Guest
Vijay Mareddy

I have some test cases which need to run for both FrontOfficeUAT DB as well as BackOfficeUAT DB ..Will this @ActiveProfiles({“fo”,”bo”}) run the test twice that is one for each profile ?

Eugen Paraschiv
Guest

Hey Vijay,
No it won’t – it will simply mean that you have both profiles active.
Cheers,
Eugen.