Skip to main content

Spring Profiles

In real world deployment, Spring Profiles are one of the critical cpmponent of a spring application and no difference in spring boot.

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

@Profile on a bean

Let's start simple and look at how we can make a bean belong to a particular profile. We use 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 example, the component is activated only if dev profile is not active:

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

Declare Profiles in XML

Profiles can also be configured in XML. The beans tag has a profile attribute, which takes comma-separated values of the applicable profiles:

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

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

*** Set profile with 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");
}
}

*** Set profile with ConfigurableEnvironment***

@Autowired
private ConfigurableEnvironment env;

env.setActiveProfiles("someProfile");

*** Set profile with Context Parameter in web.xml***

Similarly, we can define the active profiles in the web.xml file of the web application, 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>

*** Set profile with JVM System Parameter***

The profile names can also be passed in via a JVM system parameter. These profiles will be activated during application startup:

-Dspring.profiles.active=dev

*** Set profile with Maven***

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 @spring.profiles.active@ placeholder in application.properties:

spring.profiles.active=@spring.profiles.active@

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.

*** Set Spring Boot profile with Maven***

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

Conclusion

So far, we've looked at multiple ways of activating profiles. Let's now see which one has priority over the other and what happens if we 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