Archive

Archive for August, 2012

Spring Environment Profiles

August 26th, 2012 1 comment

Often time our web applications depend on properties that can change depending upon the environment (DEV/Stage/Production) the application is running. Examples of these include admin email addresses or URLs to communicate with web services. I am a big advocate of promoting the same war file across all the environments. In order to achieve that, I create separate property files and bundle them in the war file. Couple years ago, I wrote a custom Properties Holder implementation that would look at a JNDI key “Environment” and load the appropriate property file. Spring 3.1 introduces Environment Profiles that simplifies this entire process.

In this blog, I will create a web application and three property files each holding an email address that is specific to an environment. Then I will create bean profile definitions in Spring context file and activate them external to the web application.

We start by creating a Maven based web application using my Spring archetype. Here is the generated web application:
Spring MVC Maven Project

The next step is to create the following three property files in the src->main->resources folder:
Project_Dev.Properties

Project_Test.Properties

Project_Prod.Properties

Now, let’s modify the applicationContext.xml file to include the bean profiles each loading their respective property files. Here is the modified application-Context.xml file:


<?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"
       xmlns:util="http://www.springframework.org/schema/util"
       xmlns:jee="http://www.springframework.org/schema/jee"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd 
       http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.1.xsd
       http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd
       http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.1.xsd">
	
	<!-- Load the dev property files by default -->
    <util:properties id="projectProperties" location="classpath:project_dev.properties"/>
 
 	<beans profile="Test">
 		<util:properties id="projectProperties" location="classpath:project_test.properties"/>
 	</beans>
 	
 	<beans profile="Prod">
 		<util:properties id="projectProperties" location="classpath:project_prod.properties"/>
 	</beans>
       
</beans>       		

	

Notice that we are using Spring’s new 3.1 schema definitions in the context file. The context file has two profiles one for test and one for production. By default, Spring would load all the properties from the project_dev.properties file. Also observe that we have used the same id for all the util:properties beans.

We then modify the HomeController class and home.jsp file to read and display the “admin.email” property. We do that using the @Value annotation in the HomeController and add it to Model as shown below:


package com.inflinx.blog.springprofiles.web.controller;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

@Controller
@RequestMapping("/home.html")
public class HomeController 
{
	@Value("#{projectProperties.adminEmail}") 
	private String adminEmail;
	
	@RequestMapping(method = RequestMethod.GET)
	public String showHome(Model model) 
	{
		model.addAttribute("adminEmail", adminEmail);
		return "home";
	}
	
}

Finally, we modify the home.jsp page to show the email property:

<%@ taglib uri=”http://java.sun.com/jsp/jstl/core” prefix=”c” %>
<%@ page session=”false” %>
<html>
<head>
<title>Home</title>
</head>
<body>
<h1>
Admin Email: ${adminEmail}
</h1>

</body>
</html>

Deploy the application and you should see the default dev admin email in the browser:
Browser Dev Email

To activate the Test profile, add the Environment Variable spring.profiles.active with value Test. In Windows, you can do that by going to Advanced Settings -> Environment Variable -> New
Environment Variables

If you are running your Application Server from Eclipse, restart Eclipse and redeploy the app. In the logs you should be able to see that Spring has activated Test profile:
Spring Active Profiles

Upon refreshing the browser, you should see the new admin email:
Test Admin Email

Categories: Maven, Spring Tags: