Spring Profiles | JavaInUse



Spring Profiles



Overview

Spring Profiles allows users to register beans depending on the profile(dev, test, prod etc).
So when the application is running in DEV only certain beans can be loaded and when in PROD certain other beans can be loaded.

Lets Begin

For example suppose a Developer wants to use different database configurations for different environments like Dev, Prod etc.
For this the developer would have created a DAO class and inserted the datasource object as below
public class BusinessDAO  {
    private DataSource dataSource;

    public void setDataSource(DataSource dataSource) {
        this.dataSource = dataSource;
    }
}
Using Traditional Spring features without profile the developer needs to configure the database config as follows
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName">
            <value></value>
        </property>
        <property name="url">
            <value></value>
        </property>
        <property name="username">
            <value></value>
        </property>
        <property name="password">
            <value></value>
        </property>
</bean> 
Then using the PropertyPlaceholderConfigurer the developer could load either the db-dev.properties or db-prod.properties.
This approach is fine if the user wants to load exactly the same database configuration with different values in all environments.
The problem arises when the developer wants to have different DB configurations in different environments.

So suppose in dev environment the developer wants the following datasource config -
<bean id="dataSource" class="org.springframework.jdbc.datasource.SimpleDriverDataSource">
 <property name="driverClassName">
            <value></value>
        </property>
        <property name="url">
            <value></value>
        </property>
        <property name="username">
            <value></value>
        </property>
        <property name="password">
            <value></value>
        </property>
</bean>
but in prod environment wants the datasource config as follows-
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName">
            <value></value>
        </property>
        <property name="url">
            <value></value>
        </property>
        <property name="username">
            <value></value>
        </property>
        <property name="password">
            <value></value>
        </property>
</bean> 
As the developer wants different configurations based on environment only using propertyplaceholder wont suffice and spring profiles should be used.

Spring profiles using Spring XML-
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
 xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
  http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd">
<!--Profile for the Dev Environment-->
<beans profile="dev">
 	<bean id="dataSource" class="org.springframework.jdbc.datasource.SimpleDriverDataSource">
		<property name="driverClassName">
			<value></value>
		</property>
		<property name="url">
			<value></value>
		</property>
		<property name="username">
			<value></value>
		</property>
		<property name="password">
			<value></value>
		</property>
	</bean>

	<context:property-placeholder location="dev-db.properties" ignore-unresolvable="true"/>
</beans>

<!--Profile for the Prod Environment-->
<beans profile="prod">
	<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
		<property name="driverClassName">
			<value></value>
		</property>
		<property name="url">
			<value></value>
		</property>
		<property name="username">
			<value></value>
		</property>
		<property name="password">
			<value></value>
		</property>
	</bean> 

	<context:property-placeholder location="dev-prod.properties"
                        ignore-unresolvable="true"/>
</beans>

</beans>
Spring Profiles using Java Config-
@Configuration 
@Profile("dev")
public class DevDBConfig {
	
	@Bean 
	public DataSource devDataSource() { 
	 {
		//Dev based config 
		
		return dataSource; 
	
	 }
}
@Configuration
@Profile("prod")
public class ProdDBConfig {

 @Bean 
 public DataSource devDataSource() { 
  {
   //Prod based config 
   
   return dataSource;
  }
} 

Enabling Profile-
Now that multiple profiles have been created, how to select the required profile.
This can be done in following ways
  • Using Spring context environment.
    ctx.getEnvironment().setActiveProfiles("prod");
  • Using system property
    System.setProperty("spring.profiles.active", "dev");
  • Another way to change the profile is to pass a system parameter at run time
    -Dspring.profiles.active="prod"
  • Enabling profile in web.xml
    <context-param>
        <param-name>spring.profiles.active</param-name>
        <param-value>prod</param-value>
    </context-param>