深入Spring IOC源码之Resource(四)

2014-11-24 10:36:17 · 作者: · 浏览: 2

if (this.clazz != null) {

is = this.clazz.getResourceAsStream(this.path);

}

else {

is = this.classLoader.getResourceAsStream(this.path);

}

if (is == null) {

throw new FileNotFoundException(

getDescription() + " cannot be opened because it does not exist");

}

return is;

}

public URL getURL() throws IOException {

URL url = null;

if (this.clazz != null) {

url = this.clazz.getResource(this.path);

}

else {

url = this.classLoader.getResource(this.path);

}

if (url == null) {

throw new FileNotFoundException(

getDescription() + " cannot be resolved to URL because it does not exist");

}

return url;

}

public File getFile() throws IOException {

return ResourceUtils.getFile(getURL(), getDescription());

}

protected File getFileForLastModifiedCheck() throws IOException {

URL url = getURL();

if (ResourceUtils.isJarURL(url)) {

URL actualUrl = ResourceUtils.extractJarFileURL(url);

return ResourceUtils.getFile(actualUrl);

}

else {

return ResourceUtils.getFile(url, getDescription());

}

}

public Resource createRelative(String relativePath) {

String pathToUse = StringUtils.applyRelativePath(this.path, relativePath);

return new ClassPathResource(pathToUse, this.classLoader, this.clazz);

}

InputStreamResource类

InputStreamResource是对InputStream的封装,它接收InputStream作为构造函数参数,它的isOpen总是返回true,并且只能被读取一次(即getInputStream方法只能被调用一次),exists、isReadable方法也总是返回true。由于它不能被多次读取,只有当不用多次读取的时候才使用该类,并且只有当没有其他可用Resource类时才使用该类。在Spring内部貌似没有使用它。它只实现了getInputStream方法:

public InputStream getInputStream() throws IOException, IllegalStateException {

if (this.read) {

throw new IllegalStateException("InputStream has already been read - " +

"do not use InputStreamResource if a stream needs to be read multiple times");

}

this.read = true;

return this.inputStream;

}

DescriptiveResource类

DescriptiveResource是对非物理资源的Description的封装。它实现了getDescription()方法。Resource中Description属性主要用于错误处理时能更加准确的打印出错位置的信息,DescriptiveResource提供对那些需要提供Resource接口中的Description属性作为错误打印信息的方法自定义的描述信息。比如在BeanDefinitionReader中,在仅仅使用InputSource作为源加载BeanDefinition时,就可以使用DescriptiveResource定义自己的Description,从而在出错信息中可以方便的知道问题源在哪里。

BeanDefinitionResource类

在Spring中Resource可以用于非物理资源的抽,BeanDefinitionResource是对BeanDefinition的封装。BeanDefinitionResource类似DescriptiveResource,它也只实现了getDescription()方法,用于在解析某个BeanDefinition出错时显示错误源信息:

public String getDescription() {

return "BeanDefinition defined in " + this.beanDefinition.getResourceDescription();

}

ContextResource接口

在Spring中还定义了ContextResource接口,继承自Resource接口,只包含一个方法:

public interface ContextResource extends Resource {

String getPathWithinContext();

}

getPathWithContext()方法相对于Context的路径,如ServletContext、PortletContext、classpath、FileSystem等,在Spring core中它有两个实现类FileSystemContextResource、ClassPathContextResource,他们分别是FileSystemResourceLoader和DefaultResourceLoader中的内部类,他们对getPathWithContext()方法的实现只是简单的返回path值。

另外,在Spring Web模块中,有一个ServletContextResource实现类,它使用ServletContext和path作为参数构造,getInputStream、getURL、getURI、getFile等方法中将实现代理给ServletContext,其中getP