深入Spring IOC源码之Resource(二)

2014-11-24 10:36:17 · 作者: · 浏览: 1
ription属性、equals、hashCode等方法的实现;所有其他方法(exists、isReadable、getURL等)都代理给File对象;createRelative方法中使用path计算相对路径,其算法是:找到最后一个路径分隔符(/),将相对路径添加到该分隔符之后,传入的相对路径可以是以路径分割符(/)开头,也可以不以分隔符(/)开头,他们的效果是一样的,对相对路径存在的“.”和“..”会在创建FileSystemResource类时处理。最后,当使用将一个目录的File对象构建FileSystemResource时,调用createRelative方法,其相对路径的父目录和当前FileSystemResource的父目录相同,比如使用”/home/Levin/dir1”目录创建FileSystemResource对象,该Resource对象调用createRelative,并传入”file”,那么出现的结果为”/home/Levin/file”,如果要得到”/home/Levin/dir1/file”,那么构建FileSystemResource时,应该传入”/home/Levin/dir1/”字符串。

public boolean isReadable() {

return (this.file.canRead() && !this.file.isDirectory());

}

public InputStream getInputStream() throws IOException {

return new FileInputStream(this.file);

}

public Resource createRelative(String relativePath) {

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

return new FileSystemResource(pathToUse);

}

public String getDescription() {

return "file [" + this.file.getAbsolutePath() + "]";

}

UrlResource类

UrlResource是对URL和URI的封装。在构建UrlResource时可以传入URL、URI和Path字符串(带协议字符串,如”file:”)。在UrlResource内部还会创建一个cleanedUrl,它是规格化(计算“.”和“..”后的值),该URL将会用于equals、hashCode方法的实现。

在getInputStream方法实现中,它使用URL.openConnection()方法获取URLConnection,后调用该URLConnection的getInputStream方法。对getFile()方法,只支持文件系统的资源,即URL字符串的协议部分为”file:”。UrlResource还支持从jar、zip、vfszip、wsjar等内部文件,以jar为例,这些文件的字符串表达为:jar:file://jarfile.jar!//filename,如jar:file:/E:/Program%20Files/eclipse-juno/plugins/org.junit_4.10.0.v4_10_0_v20120426-0900/junit.jar!/org/junit/Test.class,然而这些内部文件本身并没有lastModified的属性,因而对这些内部文件,UrlResource将jar、zip等文件的lastModified视为这些内部文件的lastModified属性。对createRelative方法,直接使用URL提供的构造函数,忽略传入的relativePath中的路径分隔符“/”。

public InputStream getInputStream() throws IOException {

URLConnection con = this.url.openConnection();

con.setUseCaches(false);

return con.getInputStream();

}

protected File getFileForLastModifiedCheck() throws IOException {

if (ResourceUtils.isJarURL(this.url)) {

URL actualUrl = ResourceUtils.extractJarFileURL(this.url);

return ResourceUtils.getFile(actualUrl);

}

else {

return getFile();

}

}

public Resource createRelative(String relativePath) throws MalformedURLException {

if (relativePath.startsWith("/")) {

relativePath = relativePath.substring(1);

}

return new UrlResource(new URL(this.url, relativePath));

}

ClassPathResource类

对classpath下资源的封装,或者说是对ClassLoader.getResource()方法或Class.getResource()方法的封装。它支持在当前classpath中读取资源文件。可以传入相对classpath的文件全路径名和ClassLoader构建ClassPathResource,或忽略ClassLoader采用默认ClassLoader(即Thread Context ClassLoader),此时在getInputStream()方法实现时时会使用ClassLoader.getResourceAsStream()方法,由于使用ClassLoader获取资源时默认相对于classpath的根目录,因而构造函数会忽略开头的“/”字符。ClassPathResource还可以使用文件路径和Class作为参数构建,此时若文件路径以“/”开头,表示该文件为相对于classpath的绝对路径,否则为相对Class实例的相对路径,在getInputStream()方法实现时使用Class.getResourceAsStream()方法。

getFile()方法只支持存在于文件系统中的资源;对lastModified的属性,若是jar、zip等文件中的资源,则采用jar、zip文件本身的lastModified属性;equals会同时判断path、classloader、clazz字段,而hashCode则只使用path。

public InputStream getInputStream() throws IOException {

InputStream is = null;