对于spring配置文件的编写,我想,对于经历过庞大项目的人,都有那种恐惧的心理,太多的配置文件。不过,分模块都是大多数人能想到的方法,但是,怎么分模块,那就是仁者见仁,智者见智了。我的策略是使用import。
基本代码格式如下
web.xml
<?xml version="1.0" encoding="gb2312"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
<beans> <import resource="CTIContext.xml" />
<import resource="customerContext.xml" />
<import resource="customerServingContext.xml" />
<import resource="manageContext.xml" />
<import resource="routineContext.xml" />
<import resource="systemContext.xml" />
</beans>
applicationContext.xml文件中使用import的方式导入有模块配置文件,以后若有新模块的加入,那就可以简单修改这个文件了,这样大大的简化了配置文件后期的复杂程度;
Spring 的解析代码如下;
/**
* Parse an "import" element and load the bean definitions from the given resource
* into the bean factory.
*/
protected void importBeanDefinitionResource(Element ele) {
// 获取resource 属性
String location = ele.getAttribute(RESOURCE_ATTRIBUTE);
// 如果不存在resource ,则不做任何处理
if (!StringUtils.hasText(location)) {
getReaderContext().error("Resource location must not be empty", ele);
return;
} // Resolve system properties: e.g. "${user.dir}"
// 解析系统属性.格式如 : ${user.dir}
location = environment.resolveRequiredPlaceholders(location); Set<Resource> actualResources = new LinkedHashSet<Resource>(4); // Discover whether the location is an absolute or relative URI
// 判断是绝对地址还是相对地址
boolean absoluteLocation = false;
try {
absoluteLocation = ResourcePatternUtils.isUrl(location)
|| ResourceUtils.toURI(location).isAbsolute();
}
catch (URISyntaxException ex) {
// cannot convert to an URI, considering the location relative
// unless it is the well-known Spring prefix "classpath*:"
} // Absolute or relative?
// 如果是绝对地址,则直接根据地址加载对应的配置文件
if (absoluteLocation) {
try {
int importCount = getReaderContext().getReader().loadBeanDefinitions(
location, actualResources);
if (logger.isDebugEnabled()) {
logger.debug("Imported " + importCount
+ " bean definitions from URL location [" + location + "]");
}
}
catch (BeanDefinitionStoreException ex) {
getReaderContext().error(
"Failed to import bean definitions from URL location ["
+ location + "]", ele, ex);
}
}
else {
// No URL -> considering resource location as relative to the current file.
// 如果是相对地址,则计算出绝对地址
try {
int importCount;
// Resource 的多个子类 ,如 VfsResource,FileSystemResource,ClassPathResource
// 而每个Resource的createRelative 方法都不太一样所以这里先使用子类的方法尝试解析,
Resource relativeResource = getReaderContext().getResource().createRelative(
location);
if (relativeResource.exists()) {
importCount = getReaderContext().getReader().loadBeanDefinitions(
relativeResource);
actualResources.add(relativeResource);
}
else {
// 如果解析不成功,则使用默认解析器ResourcePatternResolver 进行解析
String baseLocation = getReaderContext().getResource().getURL().toString();
importCount = getReaderContext().getReader().loadBeanDefinitions(
StringUtils.applyRelativePath(baseLocation, location),
actualResources);
}
if (logger.isDebugEnabled()) {
logger.debug("Imported " + importCount
+ " bean definitions from relative location [" + location
+ "]");
}
}
catch (IOException ex) {
getReaderContext().error("Failed to resolve current resource location",
ele, ex);
}
catch (BeanDefinitionStoreException ex) {
getReaderContext().error(
"Failed to import bean definitions from relative location ["
+ location + "]", ele, ex);
}
}
// 解析后进行监听器激活处理
Resource[] actResArray = actualResources.toArray(new Resource[actualResources.size()]);
getReaderContext().fireImportProcessed(location, actResArray, extractSource(ele));
}