4.2 Resource 接口
相对标准 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对象(前提是底层实现可兼容的,也支持该功能)。
在 spring 里,Resource抽象有着相当广泛的使用,比如,当需要一个资源时,Resource 可以作为方法签名里的一个参数类型。在 spring api 中,有些方法(如各种 ApplicationContext 实现的构造函数)会直接采用普通格式的String路径来创建合适的Resource,调用者也可以通过在路径里带上指定的前缀来创建特定 Resource 实现。
Resource 接口(实现)不仅可以被 spring 大量的应用,其也非常适合作为你编程中访问资源的辅助工具类。当你仅需要使用到 Resource 接口实现时,可以直接忽略 spring 的其余部分。单独使用 Rsourece 实现,会造成代码与 spring 的部分耦合,可也仅耦合了其中一小部分辅助类,而且你可以将 Reource 实现作为 URL 的一种访问底层更为有效的替代,与你引入其他库来达到这种目的是一样的。
需要注意的是Resource实现并没有去重新发明轮子,而是尽可能地采用封装。举个例子,UrlResource 里就封装了一个 URL 对象,在其内的逻辑就是通过封装的 URL 对象来完成的。