资源抽象接口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具体实现关系
- 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 访问同一个文件资源:
在获取资源后,用户就可以通过 Resource 接口定义的多个方法访问文件的数据和其他的信息:如可以通过 getFileName()获取文件名,通过 getFile()获取资源对应的 File 对象,
通过 getInputStream()直接获取文件的输入流。此外,还可以通过 createRelative(String relativePath)在资源相对地址上创建新的文件。
在 Web 应用中,用户还可以通过 ServletContextResource 以相对于 Web 应用根目录的
方式访问文件资源,如下所示:
对于位于远程服务器(Web 服务器或 FTP 服务器)的文件资源,用户可以方便地通过UrlResource 进行访问。
资源加载时默认采用系统编码读取资源内容,如果资源文件采用特殊的编码格式,那么可以通过 EncodedResource 对资源进行编码,以保证资源内容操作的正确性;
资源加载利器
为了访问不同类型的资源,必须使用相应的 Resource 实现类,这是比较麻烦的。
Spring 提供了一个强大加载资源的机制,不但能够通过“classpath:”、“file:”等资源地址前缀识别不同的资源类型,还支持 Ant 风格带通配符的资源地址
首先,我们来了解一下 Spring 支持哪些资源类型的地址前缀:
资源加载器
Spring 定义一套资源加载的接口,并提供了实现类
ResourceLoader 接口仅有一个 getResource(String location)的方法,可以根据一个资源地址加载文件资源,不过,资源地址仅支持带资源类型前缀的表达式,不支持 Ant 风格的资源路径表达式。ResourcePatternResolver 扩展 ResourceLoader 接口,定义了一个新的接口方法:
getResources(String locationPattern),
总结
通过Resource资源访问利器,可以访问各种类型的资源文件,但是需要匹配对应的方法。为了简便,提供了ResourcePatternResolver的接口进行访问,他下面有一个实现类PathMatchingResourcePattemReoulver
可以通过此方法,进行访问,支持ant风格同时兼容访问方法的不同。