Skip to content

Instantly share code, notes, and snippets.

@schakko
Created September 19, 2013 09:04
Show Gist options
  • Save schakko/6620919 to your computer and use it in GitHub Desktop.
Save schakko/6620919 to your computer and use it in GitHub Desktop.
package de.neosit.spring.context;
import java.io.IOException;
import javax.servlet.ServletContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationContextInitializer;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.core.env.AbstractEnvironment;
import org.springframework.core.io.support.ResourcePropertySource;
import org.springframework.util.StringUtils;
import org.springframework.web.context.support.XmlWebApplicationContext;
/**
* This context enables the selection of profiles which were introduced with
* Spring 3.1. The primary idea behind this class came from Alex Radzin /
* {@link http
* ://alexradzin.blogspot.de/2012/04/initiate-current-spring-profile-from .html}
* .
*
* You have to use the following context parameter inside your web.xml to enable
* this initializer:
*
* <pre>
* &lt;context-param&gt;
* &lt;param-name&gt;contextInitializerClasses&lt;/param-name&gt;
* &lt;param-value&gt;de.neosit.spring.context.ProfileContextInitializer&lt;/param-value&gt;
* &lt;/context-param&gt;
* </pre>
*
* <strong>Order</strong>
* <ul>
* <li>If application was started with -Dspring.profiles.active, do nothing.</li>
* <li>Lookup {@value #USE_SPRING_PROFILE_PROPERTY} inside web.xml's
* context-param tag. If it does exist, use the defined value active profile.</li>
* <li>If no {@value #USE_SPRING_PROFILE_PROPERTY} is given, lookup
* context-param {@value #LOAD_PROPERTY_FILE} inside the web.xml. If it does
* exist, load the resource(s). One of the resources should contain
* <em>spring.profiles.active</em> parameter. The value behind this parameter
* can be dynamically replaced with Maven or Ant during the build process.</li>
* <li>If no {@value #LOAD_PROPERTY_FILE} is defined, the resource
* "classpath:profile.properties" will be included. The initializer throws a
* {@link RuntimeException} if it does not exist.</li>
* </ul>
*
* @author Christopher Klein
*
*/
public class ProfileContextInitializer implements
ApplicationContextInitializer<ConfigurableApplicationContext> {
Logger log = LoggerFactory.getLogger(ProfileContextInitializer.class);
public final static String DEFAULT_PROFILE_PROPERTY_FILE = "classpath:profile/active.properties";
public final static String USE_SPRING_PROFILE_PROPERTY = "useSpringProfile";
public final static String LOAD_PROPERTY_FILE = "additionalPropertySources";
public void initialize(ConfigurableApplicationContext applicationContext) {
log.info("Initializing profile context");
String additionalPropertySources = System
.getProperty(LOAD_PROPERTY_FILE);
String profilesSysProp = System
.getProperty(AbstractEnvironment.ACTIVE_PROFILES_PROPERTY_NAME);
if (!StringUtils.isEmpty(profilesSysProp)) {
log.info("Spring profile was selected by global configuration parameter (active Spring profiles: "
+ profilesSysProp + ")");
return;
}
if (applicationContext.getClass().isAssignableFrom(
XmlWebApplicationContext.class)) {
ServletContext ctx = ((XmlWebApplicationContext) applicationContext)
.getServletContext();
String profile = ctx.getInitParameter(USE_SPRING_PROFILE_PROPERTY);
if (!StringUtils.isEmpty(profile)) {
log.info("Spring profile selected by web.xml configuration setting "
+ USE_SPRING_PROFILE_PROPERTY
+ " (active Spring profiles: " + profile + ")");
applicationContext.getEnvironment().setActiveProfiles(profile);
return;
}
String overrideAdditionalPropertySources = ctx
.getInitParameter(LOAD_PROPERTY_FILE);
if (!StringUtils.isEmpty(overrideAdditionalPropertySources)) {
log.info("Loading additional property files by web.xml configuration setting "
+ LOAD_PROPERTY_FILE
+ ". This file should contain the spring.profiles.active parameter.");
additionalPropertySources = overrideAdditionalPropertySources;
}
}
if (StringUtils.isEmpty(additionalPropertySources)) {
log.warn("No additional property sources defined. Falling back to "
+ DEFAULT_PROFILE_PROPERTY_FILE);
additionalPropertySources = DEFAULT_PROFILE_PROPERTY_FILE;
}
try {
log.info("Loading additional property sources from "
+ additionalPropertySources);
ResourcePropertySource propertySource = new ResourcePropertySource(
additionalPropertySources);
Object assignedProfile = propertySource
.getProperty(AbstractEnvironment.ACTIVE_PROFILES_PROPERTY_NAME);
if (StringUtils.isEmpty(assignedProfile)) {
log.warn("None of the defined property source from "
+ additionalPropertySources + " contains "
+ AbstractEnvironment.ACTIVE_PROFILES_PROPERTY_NAME);
} else {
log.info("One of the additional property sources contained "
+ AbstractEnvironment.ACTIVE_PROFILES_PROPERTY_NAME
+ " (active Spring profiles: "
+ (String) assignedProfile + ")");
// prevent circular resolvement
if (((String) assignedProfile).startsWith("${")) {
throw new RuntimeException(
"The profile file "
+ additionalPropertySources
+ " contains a profile statement but this is invalid as it although uses Spring EL ("
+ assignedProfile
+ "). Please check your Maven build process that the environment variable has been correctly replaced.");
}
}
applicationContext.getEnvironment().getPropertySources()
.addFirst(propertySource);
} catch (IOException e) {
log.error("Unable to load property source "
+ additionalPropertySources, e);
throw new RuntimeException(e);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment