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 specific 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. 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.3. 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.4. Environment Variable
In a Unix environment, profiles can also be activated via environment variable:
export spring_profiles_active=dev
4.5. @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:
- Context parameter in web.xml
- WebApplicationInitializer
- JVM System parameter
- Environment variable
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 datasource 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 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 injects 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. 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 an Eclipse based project, so it should be easy to import and run as it is.
I usually post about Spring stuff on Google+ - you can follow me there: