Last active
August 29, 2015 13:56
-
-
Save agentgt/8870316 to your computer and use it in GitHub Desktop.
Spring Configuration Overlaying
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import static java.util.Arrays.asList; | |
import static org.springframework.util.StringUtils.hasText; | |
import java.io.IOException; | |
import java.util.ArrayList; | |
import java.util.List; | |
import javax.servlet.ServletContext; | |
import org.slf4j.Logger; | |
import org.slf4j.LoggerFactory; | |
import org.springframework.context.ApplicationContext; | |
import org.springframework.core.io.Resource; | |
import org.springframework.core.io.support.ResourcePropertySource; | |
import org.springframework.util.StringUtils; | |
public class AbstractConfigResourcesFactoryBean { | |
private String defaultResources; | |
private boolean searchSystemEnvironment = true; | |
private String parameterName; | |
private String servletContextParamValue; | |
private ApplicationContext applicationContext; | |
private static enum ConfigParameterType { | |
SYSTEM_ENVIRONMENT(true), | |
SERVLET_CONFIG(true), | |
DEFAULT(false); | |
private boolean failIfParameterProvidedButNoneFound; | |
private ConfigParameterType(boolean failIfParameterProvidedButNoneFound) { | |
this.failIfParameterProvidedButNoneFound = failIfParameterProvidedButNoneFound; | |
} | |
public boolean isFailIfParameterProvidedButNoneFound() { | |
return failIfParameterProvidedButNoneFound; | |
} | |
} | |
public void setDefaultResources(String defaultValue) { | |
this.defaultResources = defaultValue; | |
} | |
public Resource[] getResources() { | |
ArrayList<Resource> rs = new ArrayList<Resource>(); | |
add(rs, defaultResources, ConfigParameterType.DEFAULT); | |
add(rs, servletContextParamValue, ConfigParameterType.SERVLET_CONFIG); | |
add(rs, resolveSystemProperty(parameterName), ConfigParameterType.SYSTEM_ENVIRONMENT); | |
logger.info("Found the following\nconfig resources:\n " | |
+ StringUtils.collectionToDelimitedString(rs, "\n ")); | |
return rs.toArray(new Resource[rs.size()]); | |
} | |
public List<ResourcePropertySource> getResourcePropertySources() throws IOException { | |
Resource[] rs = getResources(); | |
List<ResourcePropertySource> rp = new ArrayList<ResourcePropertySource>(rs.length); | |
for (Resource r: rs) { | |
rp.add(new ResourcePropertySource(r)); | |
} | |
return rp; | |
} | |
private int add(ArrayList<Resource> rs, String pattern, ConfigParameterType type) { | |
Resource[] r = loadConfig(pattern, type); | |
int files = -1; | |
if (r != null) { | |
files = r.length; | |
rs.addAll(asList(r)); | |
} | |
return files; | |
} | |
private Resource[] loadConfig(String config, ConfigParameterType t) { | |
if (! hasText(config) ) { | |
logger.info("No config location specified by: {} for parameter: {}", t, parameterName); | |
return null; | |
} | |
logger.info("Config location specified by: " + t + " for parameter: " + parameterName | |
+ " Loading config from: " + config); | |
try { | |
Resource[] resources = applicationContext.getResources(config); | |
if (t.isFailIfParameterProvidedButNoneFound() && resources != null && resources.length == 0) { | |
throw new RuntimeException("Error no config files found for: " + config); | |
} | |
return resources; | |
} catch (IOException e) { | |
throw new RuntimeException("Error loading config: " + config, e); | |
} | |
} | |
/** | |
* Set the name of the ServletContext init parameter to expose. | |
* @param initParamName | |
*/ | |
public void setParameterName(String initParamName) { | |
this.parameterName = initParamName; | |
} | |
public void setServletContext(ServletContext servletContext) { | |
if (this.parameterName == null) { | |
throw new IllegalArgumentException("initParamName is required"); | |
} | |
String contextPath = servletContext.getContextPath().replaceAll("/", ""); | |
String displayName = servletContext.getServletContextName(); | |
List<String> parameterNamesToTry = new ArrayList<String>(); | |
if (hasText(contextPath) && hasText(displayName)) { | |
parameterNamesToTry.add(displayName + "-" + contextPath + "-" + parameterName); | |
} | |
if (hasText(contextPath)) { | |
parameterNamesToTry.add(contextPath + "-" + parameterName); | |
} | |
if (hasText(displayName)) { | |
parameterNamesToTry.add(displayName + "-" + parameterName); | |
} | |
parameterNamesToTry.add(parameterName); | |
for (String p : parameterNamesToTry) { | |
this.servletContextParamValue = servletContext.getInitParameter(p); | |
if (this.servletContextParamValue != null) { | |
logger.info("Using servlet context parameter name: " + p); | |
break; | |
} | |
} | |
if (this.servletContextParamValue == null) { | |
logger.debug("No ServletContext init parameter with any of these names '" + | |
parameterNamesToTry + "' found"); | |
} | |
} | |
/** | |
* Resolve the given key as JVM system property, and optionally also as | |
* system environment variable if no matching system property has been found. | |
* @param key the placeholder to resolve as system property key | |
* @return the system property value, or <code>null</code> if not found | |
* @see #setSearchSystemEnvironment | |
* @see java.lang.System#getProperty(String) | |
* @see java.lang.System#getenv(String) | |
*/ | |
protected String resolveSystemProperty(String key) { | |
try { | |
String value = System.getProperty(key); | |
if (value == null && this.searchSystemEnvironment) { | |
value = System.getenv(key); | |
} | |
return value; | |
} | |
catch (Throwable ex) { | |
if (logger.isDebugEnabled()) { | |
logger.debug("Could not access system property '" + key + "': " + ex); | |
} | |
return null; | |
} | |
} | |
public void setSearchSystemEnvironment(boolean searchSystemEnvironment) { | |
this.searchSystemEnvironment = searchSystemEnvironment; | |
} | |
public void setApplicationContext(ApplicationContext applicationContext) { | |
this.applicationContext = applicationContext; | |
} | |
private static final Logger logger = LoggerFactory.getLogger(AbstractConfigResourcesFactoryBean.class); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import static java.util.Collections.reverse; | |
import java.io.IOException; | |
import java.util.List; | |
import org.slf4j.Logger; | |
import org.slf4j.LoggerFactory; | |
import org.springframework.context.ApplicationContextInitializer; | |
import org.springframework.context.ConfigurableApplicationContext; | |
import org.springframework.core.io.support.ResourcePropertySource; | |
import org.springframework.util.StringUtils; | |
import org.springframework.web.context.WebApplicationContext; | |
public class MyConfigContextInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext> { | |
@Override | |
public void initialize(ConfigurableApplicationContext context) { | |
ContextInitializerConfigResources resources = new ContextInitializerConfigResources(context, | |
"MyConfigParameter", | |
"classpath*:META-INF/spring/*.properties"); | |
List<ResourcePropertySource> propertyFiles; | |
try { | |
propertyFiles = resources.getResourcePropertySources(); | |
} catch (IOException e) { | |
throw new RuntimeException(e); | |
} | |
//Spring prefers primacy ordering so we reverse the order of the files. | |
reverse(propertyFiles); | |
for (ResourcePropertySource rp : propertyFiles) { | |
context.getEnvironment().getPropertySources().addLast(rp); | |
} | |
String profiles = context.getEnvironment().getProperty("MyConfig.profiles"); | |
log.info("Using profiles: " + profiles); | |
if (StringUtils.hasText(profiles)) { | |
String[] ps = StringUtils.commaDelimitedListToStringArray(profiles); | |
context.getEnvironment().setActiveProfiles(ps); | |
} | |
} | |
private static class ContextInitializerConfigResources extends AbstractConfigResourcesFactoryBean { | |
private ContextInitializerConfigResources(ConfigurableApplicationContext context, String parameterName, String defaultResources) { | |
super(); | |
setParameterName(parameterName); | |
setDefaultResources(defaultResources); | |
setApplicationContext(context); | |
if (context instanceof WebApplicationContext) { | |
WebApplicationContext c = (WebApplicationContext) context; | |
if (c.getServletContext() != null) | |
setServletContext(c.getServletContext()); | |
} | |
setSearchSystemEnvironment(true); | |
} | |
} | |
private static final Logger log = LoggerFactory.getLogger(MyConfigContextInitializer.class); | |
} |
For Unit Testing see http://docs.spring.io/spring/docs/3.2.x/spring-framework-reference/html/testing.html#integration-testing-annotations Particularly on the initializers parameter
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Google how to setup
ApplicationContextInitializer
in Spring documentation.