Spring--Resource
在日常程序开发中,处理外部资源是很繁琐的事情,我们可能需要处理URL资源、File资源资源、ClassPath相关资源、服务器相关资源(JBoss AS 5.x上的VFS资源)等等很多资源。因此处理这些资源需要使用不同的接口,这就增加了我们系统的复杂性;而且处理这些资源步骤都是类似的(打开资源、读取资源、关闭资源),因此如果能抽象出一个统一的接口来对这些底层资源进行统一访问,是不是很方便,而且使我们系统更加简洁,都是对不同的底层资源使用同一个接口进行访问。
Spring 提供一个Resource接口来统一这些底层资源一致的访问,而且提供了一些便利的接口,从而能提供我们的生产力。
类继承图

类定义
InputStreamSource
public interface InputStreamSource {
InputStream getInputStream() throws IOException;
}
getInputStream:定位并打开资源,返回资源对应的输入流。每次调用都会返回新的输入流,调用者在使用完毕后必须关闭该资源。
Resource
public interface Resource extends InputStreamSource {
boolean exists();
boolean isReadable();
boolean isOpen();
URL getURL() throws IOException;
URI getURI() throws IOException;
File getFile() throws IOException;
long contentLength() throws IOException;
long lastModified() throws IOException;
Resource createRelative(String relativePath) throws IOException;
String getFilename();
String getDescription();
}
UrlResource
代表URL资源,用于简化URL资源访问,是对java.net.URL的包装。在java中,将不同来源的资源抽象成URL,通过注册不同的handler来处理不同来源的资源的读取逻辑。一般不同类型使用不同的前缀。
isOpen永远返回false,表示可多次读取资源。
UrlResource应该提供标准的协议前缀,一般支持如下资源访问:
- http:通过标准的http协议访问web资源,如new UrlResource(“http://地址”);
- ftp:通过ftp协议访问资源,如new UrlResource(“ftp://地址”);
- file:通过file协议访问本地文件系统资源,如new UrlResource(“file:d:/test.txt”)
但是UrlResource无法解决相对classpath路径或servletContext的处理方法,因此需要其他的Resource实现类。
ClassPathResource
代表classpath路径的资源,将使用ClassLoader进行加载资源。主要优势是方便访问类加载路径下的资源,尤其是Web应用,因为它可以自动搜索位于WEB-INF/classes下的资源文件
classpath资源存在于类路径中的文件系统中或jar包里,且isOpen永远返回false,表示可多次读取资源。
ClassPathResource加载资源替代了Class类和ClassLoader类的getResource(String name)和getResourceAsStream(String name)两个加载类路径资源方法,提供一致的访问方式。
ClassPathResource提供了三个构造器:
- public ClassPathResource(String path):使用默认的ClassLoader加载“path”类路径资源;
- public ClassPathResource(String path, ClassLoader classLoader):使用指定的ClassLoader加载“path”类路径资源;
- public ClassPathResource(String path, Class<?> clazz):使用指定的类加载“path”类路径资源,将加载相对于当前类的路径的资源;
当Spring获取资源时,路径字符串前缀是"classpath:",则系统将会自动创建ClassPathResource对象
FileSystemResource
代表java.io.File资源,对于getInputStream操作将返回底层文件的字节流,isOpen将永远返回false,从而表示可多次读取底层文件的字节流。
public static void Test_FileSystemResource() {
File file = new File("d:/test.txt");
Resource resource = new FileSystemResource(file);
if (resource.exists()) {
dumpStream(resource);
}
Assert.isTrue(!resource.isOpen());
}
当Spring获取资源时,路径字符串前缀是"file:",则系统将会自动创建FileSystemResource对象
ServletContextResource
访问Web Context下相对路径下的资源,入参的资源位置是相对于Web应用根路径的位置(工程文件夹下,WEB-INF所在的那级文件夹)。用于简化servlet容器的ServletContext接口的getResource操作和getResourceAsStream操作。
使用ServletContextResource无需关心资源是否被解压缩出来,或者直接存放在JAR文件中,都可以通过Servlet容器访问。
入参需要ServletContext和字符串类型
public class ResourceTest {
ServletContextResource resource = new ServletContextResource(servletContext,"spring.xml");
}
InputStreamResource
代表java.io.InputStream字节流,对于getInputStream操作将直接返回该字节流,因此只能读取一次该字节流,即isOpen永远返回true(其他Resource大都为false可以多次读取)
只有当没有合适的Resource实现时,才考虑使用InputStreamResource。一般考虑使用ByteArrayResource
ByteArrayResource
可多次读取数组资源,即isOpen()永远返回false
ByteArrayResource因为入参可以是byte[]类型,所以用途比较广泛,可以把从网络或者本地资源都转换为byte[]类型,然后用ByteArrayResource转化为资源。