Spring 为可以更方面的从不同的地方读取Resource,从而为我们提供了一系列加载不同的Resource的读取器的实现,
例如:
FileSystemXmlApplicationContext可以从文件系统载入Resource
ClassPathXmlApplicationContext可以从类路径载入Resource
XmlWebApplicationContext可以在web容器中载入Resource
下面我们以FileSystemXmlApplicationContext为例,来理解BeanDefinition是如何Resource定位的,下面是FileSystemXmlApplicationContext的继承体系图:
package com.bjhy.platform.criminal.search.system.test;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.AbstractXmlApplicationContext;
import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.Resource;
/**
* 从文件系统中载入Resource
*
*/
public class FileSystemXmlApplicationContext extends AbstractXmlApplicationContext {
/**
* 无参数的构造方法
*/
public FileSystemXmlApplicationContext() {
}
/**
* @param parent ApplicationContext上下文对象
*/
public FileSystemXmlApplicationContext(ApplicationContext parent) {
super(parent);
}
/**
* @param configLocation BeanDefinition所在的文件路径
* @throws BeansException BeansException异常
*/
public FileSystemXmlApplicationContext(String configLocation) throws BeansException {
this(new String[] {configLocation}, true, null);
}
/**
* @param configLocation 允许包含多个BeanDefinition所在的文件路径
* @throws BeansException BeansException异常
*/
public FileSystemXmlApplicationContext(String... configLocations) throws BeansException {
this(configLocations, true, null);
}
/**
* 这个构造函数允许configLocations包含多个BeanDefinition的文件路径,同时还允许指定自己的双亲IOC容器
* @param configLocations 允许包含多个BeanDefinition所在的文件路径
* @param parent ApplicationContext
* @throws BeansException
*/
public FileSystemXmlApplicationContext(String[] configLocations, ApplicationContext parent) throws BeansException {
this(configLocations, true, parent);
}
public FileSystemXmlApplicationContext(String[] configLocations, boolean refresh) throws BeansException {
this(configLocations, refresh, null);
}
/**
* 在对象的初始化过程中,调用refresh函数载入BeanDefinition
* @param configLocations 允许包含多个BeanDefinition所在的文件路径
* @param refresh 是否启动初始化IOC容器
* @param parent ApplicationContext
* @throws BeansException
*
*/
public FileSystemXmlApplicationContext(String[] configLocations, boolean refresh, ApplicationContext parent)
throws BeansException {
super(parent);
setConfigLocations(configLocations);
if (refresh) {
refresh();//启动BeanDefinition资源定位过程
}
}
/**
* 这是应用于文件系统中的Resource实现,通过构造一个FileSystemResource来得到一个在文件系统定位的BeanDefinition,
* 这个getResourceByPath是在BeanDefinition的loadBeanDefinition中被调用的
* loadBeanDefinition采用模板模式,具体的实现实际上由各个子类完成
*/
@Override
protected Resource getResourceByPath(String path) {
if (path != null && path.startsWith("/")) {
path = path.substring(1);
}
return new FileSystemResource(path);
}
}
<getResourceByPath的调用过程>:
FileSystemXmlApplicationContext ----调用refreshBeanFactory--->AbstractRefreshableApplicationContext -------调用getResourceByPath-->FileSystemResource----->最终返回FileSystemResource