public class ContextLoader extends org.springframework.web.context.ContextLoader {
protected final Log logger = LogFactory.getLog(this.getClass());
//该方法是创建webApplictionContext的回调方法
protected WebApplicationContext createWebApplicationContext(
ServletContext servletContext, ApplicationContext parent) throws BeansException {
// 所有待加载配置文件jar包的url字符串
List<String> jarUrls = new ArrayList<String>();
// 因为有可能在平台开发时不加载jar包中的文件
if(HiConfigHolder.getJarFile() != null){
// 找到要加载spring配置文件的jar包文件
String[] jars = HiConfigHolder.getJarFile().trim().split("[,]");
for (String jarFileName : jars) {
String hiJarUrl = null;
try {
File classFile = new File(this.getClass().getClassLoader().getResource("").toURI());
hiJarUrl = (new URL(classFile.getParentFile().toURI().toString() + "/lib/"+jarFileName)).getFile();
if(hiJarUrl != null)
jarUrls.add( URLDecoder.decode(hiJarUrl,"utf-8"));
}
catch (Exception e) {
logger.error("error:load jar file == " + jarFileName);
}
}
}
Class contextClass = determineContextClass(servletContext);
if (!ConfigurableWebApplicationContext.class.isAssignableFrom(contextClass)) {
throw new ApplicationContextException("Custom context class [" + contextClass.getName() +
"] is not of type ConfigurableWebApplicationContext");
}
List<String> allResources = new ArrayList<String>();
ConfigurableWebApplicationContext wac =
(ConfigurableWebApplicationContext) BeanUtils.instantiateClass(contextClass);
wac.setParent(parent);
wac.setServletContext(servletContext);
String configLocation = servletContext.getInitParameter(CONFIG_LOCATION_PARAM);
if (configLocation != null) {
String[] resources = StringUtils.tokenizeToStringArray(configLocation,ConfigurableWebApplicationContext.CONFIG_LOCATION_DELIMITERS);
// 第一次加载resources的目的是为jar文件中的配置所须的依赖提供支持
for (int i = 0; i < resources.length; i++) {
if(resources[i] == null || resources[i].equals(""))
continue;
if(resources[i].toUpperCase().indexOf("WEB-INF") >= 0)
allResources.add(resources[i]);
}
// 加载jar包中的配置文件
if(jarUrls.size() > 0){
for (String hiJarUrl : jarUrls) {
if(hiJarUrl != null){
Resource[] jarResources = JarResource.getInstance(new File(hiJarUrl), "*appContext-*.xml");
for (Resource resource : jarResources) {
try {
allResources.add(resource.getURL().toString());
} catch (IOException e) {}
}
}
}
}
// 第二次加载resources的目标的覆盖jar文件中有可能与classes中重名的配置文件,从而使classes中的配置文件优先于jar中的配置文件
for (int i = 0; i < resources.length; i++) {
if(resources[i] == null || resources[i].equals(""))
continue;
if(resources[i].toUpperCase().indexOf("WEB-INF") < 0)
allResources.add(resources[i]);
}
wac.setConfigLocations(allResources.toArray(new String[allResources.size()]));
}
wac.refresh();
return wac;
}
}
/**
* 获取WEB-INF/lib的路径
* @return
* lib的绝对路径
*/
private String getWebInfLibPath() {
URL url = getClass().getProtectionDomain().getCodeSource()
.getLocation();
String path = url.toString();
int index = path.indexOf("WEB-INF");
if (index == -1) {
index = path.indexOf("classes");
}
if (index == -1) {
index = path.indexOf("bin");
}
path = path.substring(0, index+7)+"/lib/";
if (path.startsWith("zip")) {// 当class文件在war中时,此时返回zip:D:/...这样的路径
path = path.substring(4);
} else if (path.startsWith("file")) {// 当class文件在class文件中时,此时返回file:/D:/...这样的路径
path = path.substring(6);
} else if (path.startsWith("jar")) {// 当class文件在jar文件里面时,此时返回jar:file:/D:/...这样的路径
path = path.substring(10);
}
try {
path = URLDecoder.decode(path, "UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return path;
}
//获取jar包中以某个字符串开头的jar
//文件,例如platform
private List<String> getPlatformJarFileName() {
String path = getWebInfLibPath();
List<String> platformJarName = new ArrayList<String>();
File file = new File(path);
File[] array = file.listFiles();
for (int i = 0; i < array.length; i++) {
//如果是jar文件并且以platform开头,记录一下改jar文件
if (array[i].isFile() &&
org.apache.commons.lang.StringUtils.isNotEmpty(array[i].getName()) &&
array[i].getName().startsWith("platform")) {
platformJarName.add(array[i].getName());
}
}
return platformJarName;
}