相对标准 url 访问机制,spring 的 Resource 接口对抽象底层资源的访问提供了一套更好的机制。
public interface Resource extends InputStreamSource {
boolean exists();
boolean isOpen();
URL getURL() throws IOException;
File getFile() throws IOException;
Resource createRelative(String relativePath) throws IOException;
String getFilename();
String getDescription();
}
public interface InputStreamSource {
InputStream getInputStream() throws IOException;
}
Resource 接口里的最重要的几个方法:
- getInputStream(): 定位并且打开当前资源,返回当前资源的 InputStream。预计每一次调用都会返回一个新的 – InputStream,因此关闭当前输出流就成为了调用者的责任。
- exists(): 返回一个 boolean,表示当前资源是否真的存在。
- isOpen(): 返回一个 boolean,表示当前资源是否一个已打开的输入流。如果结果为 true,返回的 InputStream 不能多次读取,只能是一次性读取之后,就关闭 InputStream,以防止内存泄漏。除了 InputStreamResource,其他常用 Resource 实现都会返回 false。
- getDescription(): 返回当前资源的描述,当处理资源出错时,资源的描述会用于错误信息的输出。一般来说,资源的描述是一个完全限定的文件名称,或者是当前资源的真实 url。
Resource 接口里的其他方法可以让你获得代表当前资源的 URL 或 File 对象(前提是底层实现可兼容的,也支持该功能)。
Resource抽象在Spring本身被广泛使用,作为需要资源的许多方法签名中的参数类型。 某些Spring API中的其他方法(例如各种ApplicationContext实现的构造函数)采用一个String,它以未安装或简单的形式用于创建适用于该上下文实现的资源,或者通过String路径上的特殊前缀,允许调用者 以指定必须创建和使用特定的资源实现。
Resource 接口(实现)不仅可以被 spring 大量的应用,其也非常适合作为你编程中访问资源的辅助工具类。当你仅需要使用到 Resource 接口实现时,可以直接忽略 spring 的其余部分。单独使用 Rsourece 实现,会造成代码与 spring 的部分耦合,可也仅耦合了其中一小部分辅助类,而且你可以将 Reource 实现作为 URL 的一种访问底层更为有效的替代,与你引入其他库来达到这种目的是一样的。
需要注意的是 Resource 实现并没有去重新发明轮子,而是尽可能地采用封装。举个例子,UrlResource 里就封装了一个 URL 对象,在其内的逻辑就是通过封装的 URL 对象来完成的。