基本概念
Spring 把所有能记录信息的载体,如各种类型的文件、二进制流等都称为资源。
对 Spring 开发者来说,最常用的资源就是 Spring 配置文件(通常是一份 XML 格式的文件)。
Spring 为资源访问提供了一个 Resource 接口,利用该接口来表示不同类型的资源。并且 Spring 框架本身大量使用了 Resource 接口来访问底层资源。
Resource 接口是具体资源访问策略的抽象,也是所有资源访问类所实现的接口。
内部构造
Resource 接口继承了 InputStreamSource 接口,通过该接口,可以将任意形式的资源转成流来操作。
下面来看它的源码:
- InputStreamSource
public interface InputStreamSource {
// 表示任意形式的资源都可以被转换成输入流
InputStream getInputStream() throws IOException;
}
- Resoure
public interface Resource extends InputStreamSource {
// 资源是否存在,true 表示存在
boolean exists();
// 资源是否可读,true 表示存在
boolean isReadable();
// 资源是否打开,true 表示资源只能被读取一次然后关闭以避免资源泄露
boolean isOpen();
// 当前资源能由 java.util.URL 代表时,则返回该 URL,否则抛出异常
URL getURL() throws IOException;
// 当前资源能由 java.util.URI 代表时,则返回该 URI,否则抛出异常
URI getURI() throws IOException;
// 当前资源能由 java.io.File 代表时,则返回该 File,否则抛出异常
File getFile() throws IOException;
// 资源的长度,一般是值代表的文件资源的长度
long contentLength() throws IOException;
// 资源的最后修改时间
long lastModified() throws IOException;
// 创建相对于当前资源代表的资源
// 比如当前资源代表文件资源 [d:/test/] 则 [createRelative("test.txt")] 将返回文件资源 [d:/test/test.txt]
Resource createRelative(String relativePath) throws IOException;
// 资源的文件路径,比如 File 资源就返回它的文件路径,URL 资源则返回空
String getFilename();
// 资源的描述符,通常就是资源的全路径(实际文件名或实际URL地址)。
String getDescription();
}
Resource 接口是 Spring 资源访问策略的抽象,它本身并不提供任何资源访问实现,具体的资源访问由该接口的实现类完成——每个实现类代表一种资源访问策略。
在 Spring 中存在这大量的 Resource 实现类来表示不同形式的资源。具体如下图所示:
- 继承关系
- 常见的资源类型
资源类型
Resource 实现类针对不同的的底层资源,提供了相应的资源访问逻辑,并提供便捷的包装,以利于客户端程序的资源访问。这其实也是典型的策略模式。下面来看几种常见的资源类型以及对应的访问方法。
1.ByteArrayResource
访问字节数组资源的实现类。它在其内部维护着一个字节数组,并该资源一旦创建就表示其一定存在,因此 exists 方法默认返回 true。我们可以通过将字节数组转换成 ByteArrayInputStream 来实现对它的访问。具体源码如下:
public class ByteArrayResource extends AbstractResource {
// 字节数组
private final byte[] byteArray;
// 描述,可由开发者自定义,为空时则为默认值
private final String description;
// 构造函数
public ByteArrayResource(byte[] byteArray) {
this(byteArray, "