资源抽象接口Resource

前言

JDK 所提供的访问资源的类(如 java.net.URL、File 等)并不能很好地满足各种底层资源的访问需求,比如缺少从类路径或者 Web 容器的上下文中获取资源的操作类。有鉴于此,Spring 设计了一个 Resource 接口,它为应用提供了更强的访问底层资源的能力。该接口拥有对应不同资源类型的实现类。

Resource接口里面的方法

  • boolean exists():资源是否存在;
  • boolean isOpen():资源是否打开;
  • URL getURL() throws IOException:如果底层资源可以表示成 URL,该方法返回对
    应的 URL 对象;
  • File getFile() throws IOException:如果底层资源对应一个文件,该方法返回对应的
    File 对象;
  • InputStream getInputStream() throws IOException:返回资源对应的输入流

Resource具体实现关系

java @resource详解 java中resource对象_java基础

  • ByteArrayResource:二进制数组表示的资源,二进制数组资源可以在内存中通过程序构造;
  • ClassPathResource:类路径下的资源,资源以相对于类路径的方式表示,如代码清单
  • FileSystemResource:文件系统资源,资源以文件系统路径的方式表示,如:/conf/bean.xml 等;
  • InputStreamResource:以输入流返回表示的资源;
  • ServletContextResource:为访问 Web 容器上下文中的资源而设计的类,负责以相对于 Web 应用根目录的路径加载资源,它支持以流和 URL 的方式访问,在 WAR 解包的情况下,也可以通过 File 的方式访问,该类还可以直接从 JAR 包中访问资源;
  • UrlResource:Url 封装了 java.net.URL,它使用户能够访问任何可以通过 URL 表示的资源,如文件系统的资源、HTTP 资源、FTP 资源等。

有了这个抽象的资源类后,我们就可以将 Spring 的配置信息放置在任何地方(如数据LDAP 中),只要最终可以通过 Resource 接口返回配置信息就可以了。

举例

假设有一个文件位于 Web 应用的类路径下,用户可以通过以下方式对这个文件资源进行访问

  • 通过 FileSystemResource 以文件系统绝对路径的方式进行访问;
  • 通过 ClassPathResource 以类路径的方式进行访问;
  • 通过 ServletContextResource 以相对于 Web 应用根目录的方式进行访问。

相比于通过 JDK 的 File 类访问文件资源的方式,Spring 的 Resource 实现类无疑提供了更加灵活的操作方式,用户可以根据情况选择适合的 Resource 实现类访问资源。下面,我们分别通过 FileSystemResource 和 ClassPathResource 访问同一个文件资源:

java @resource详解 java中resource对象_Web_02

java @resource详解 java中resource对象_Resource接口_03


在获取资源后,用户就可以通过 Resource 接口定义的多个方法访问文件的数据和其他的信息:如可以通过 getFileName()获取文件名,通过 getFile()获取资源对应的 File 对象,

通过 getInputStream()直接获取文件的输入流。此外,还可以通过 createRelative(String relativePath)在资源相对地址上创建新的文件。

在 Web 应用中,用户还可以通过 ServletContextResource 以相对于 Web 应用根目录的
方式访问文件资源,如下所示:

java @resource详解 java中resource对象_java基础_04


对于位于远程服务器(Web 服务器或 FTP 服务器)的文件资源,用户可以方便地通过UrlResource 进行访问。

资源加载时默认采用系统编码读取资源内容,如果资源文件采用特殊的编码格式,那么可以通过 EncodedResource 对资源进行编码,以保证资源内容操作的正确性;

java @resource详解 java中resource对象_java基础_05


资源加载利器

为了访问不同类型的资源,必须使用相应的 Resource 实现类,这是比较麻烦的。

Spring 提供了一个强大加载资源的机制,不但能够通过“classpath:”、“file:”等资源地址前缀识别不同的资源类型,还支持 Ant 风格带通配符的资源地址

首先,我们来了解一下 Spring 支持哪些资源类型的地址前缀:

java @resource详解 java中resource对象_java @resource详解_06


资源加载器

Spring 定义一套资源加载的接口,并提供了实现类

java @resource详解 java中resource对象_文件系统_07

ResourceLoader 接口仅有一个 getResource(String location)的方法,可以根据一个资源地址加载文件资源,不过,资源地址仅支持带资源类型前缀的表达式,不支持 Ant 风格的资源路径表达式。ResourcePatternResolver 扩展 ResourceLoader 接口,定义了一个新的接口方法:

getResources(String locationPattern),

java @resource详解 java中resource对象_java基础_08

总结

通过Resource资源访问利器,可以访问各种类型的资源文件,但是需要匹配对应的方法。为了简便,提供了ResourcePatternResolver的接口进行访问,他下面有一个实现类PathMatchingResourcePattemReoulver
可以通过此方法,进行访问,支持ant风格同时兼容访问方法的不同。