Spring Resources


概述

在日常程序开发中,处理外部资源是很繁琐的事情,我们可能需要处理 URL 资源、File 资源、ClassPath相关资源等等。并且在 java 中 Java .net.URL 类和用于各种 URL 前缀的标准处理程序对于所有对底层资源的访问都不够充分。处理各种各样的资源需要使用到不同的接口,这就增加了系统的复杂性。

对此 Spring 提供了 Resource 接口来统一这些底层资源一致的访问。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();

}

Resource 继承了 InputStreamSource 下面是 InputStreamSource 的内容

public interface InputStreamSource {
InputStream getInputStream() throws IOException;
}

方法解析

  1. getInputStream():每次调用都会返回一个与资源对应的 InputStream 字节流,调用者有必要在使用后关闭该资源。
  2. exists():返回 true 表示当前资源存在。
  3. isOpen():返回 Resource 代表的资源是否已经被打开。如果返回 true,则只能读取一次不能多次读取 InputStream,然后关闭,以避免资源泄漏。对于所有常见的 Resource 实现一般返回 false。
  4. getURL():返回 Resource 代表资源对应的 java.util.URL 对象。
  5. getFile():返回 Resource 代表资源对应的 java.io.File 对象。
  6. createRelative(String relativePath):用于创建相对于当前 Resource 代表资源的资源,比如当前 Resource 代表文件资源 “d:/test/” 则 createRelative(“test.txt”) 将返回表文件资源 “d:/test/test.txt” Resource 资源。
  7. getFilename():返回 Resource 代表资源对应的文件路径。
  8. getDescription():返回 Resource 代表资源的描述符,通常就是资源的全路径(实际文件名或实际 URL 地址)。

Spring 框架自身就非常广泛使用 Resource,在我们的项目中也可以使用并且可以非常方便的获取到目标资源。

内置 Resource 接口实现

  1. UrlResource
  2. ClassPathResource
  3. FileSystemResource
  4. ServletContextResource
  5. InputStreamResource
  6. ByteArrayResource

UrlResource

UrlResource 封装了 java.net.URL,可用于访问通过 URL 访问的任何对象,比如文件、HTTP 资源、FTP 资源等等。所有 URL 都有一个标准化的字符串表示,因此可以使用适当的标准化前缀来表示不同 URL 类型的 URL。一般支持如下资源访问。

  1. file:用于访问文件系统路径
new UrlResource("file:d/xxx.txt");
  1. http:用于通过 http 协议访问资源
new UrlResource("http://地址");
  1. ftp: 用于通过 ftp 访问资源
new UrlResource("ftp://地址");

ClassPathResource

ClassPathResource 表示从类路径获取资源,它使用线程上下文类加载器、给定的类加载器来加载资源。classpath 资源存在于类路径中的文件系统中或 jar 包里。

ClassPathResource 常用构造器

public ClassPathResource(String path);
public ClassPathResource(String path, @Nullable ClassLoader classLoader);
public ClassPathResource(String path, @Nullable Class<?> clazz);
  1. public ClassPathResource(String path):使用默认的类加载器记载 path 类路径下的资源
  2. public ClassPathResource(String path, @Nullable ClassLoader classLoader):使用指定的类加载器加载 path 类路径下的资源
  3. public ClassPathResource(String path, @Nullable Class clazz):只用指定的类加载 path 类路径下的资源

FileSystemResource

FileSystemResource 是 Resource 实现支持 java.io 和 java.nio.file.Path 的处理。

ServletContextResource

ServletContextResource 是 web 应用资源,ServletContext 资源的实现。用于简化 servlet 容器的 ServletContext 接口的 getResource 操作和 getResourceAsStream 操作。

InputStreamResource

InputStreamResource 是基于 InputStream 的实现,参数是一个 InputStream 只有在没有特定场景下的 Resource 的时候才使用它。

public InputStreamResource(InputStream inputStream);
public InputStreamResource(InputStream inputStream, @Nullable String description);

ByteArrayResource

ByteArrayResource 是给定一个 byte[] 数组的实现创建 ByteArrayInputStream。

ResourceLoader

ResourceLoader 用于返回 Resource 的实例。

public interface ResourceLoader {
Resource getResource(String location);
}

Spring 的 ApplicationContext 都实现了 ResourceLoader

  1. ClassPathXmlApplicationContext
  2. FileSystemXmlApplicationContext
  3. WebApplicationContext

因此可以使用 ApplicationContext 来获取资源实例,当在某个 ApplicationContext 实现类中调用 getResource 而参数没有指定特定的资源前缀时,将返回适合 ApplicationContext 实现实例的资源类型,下面是 ClassPathXmlApplicationContext 的执行代码

Resource template = ctx.getResource("some/resource/path/myTemplate.txt");

对于 ClassPathXmlApplicationContext 以上代码返回一个 ClassPathResource。

如果对 FileSystemXmlApplicationContext 实例执行相同的方法,它将返回FileSystemResource。对于 WebApplicationContext,它将返回一个 ServletContextResource。

另外也可以指定资源前缀比如 classpath: 强制使用 ClassPathResource 无论 ApplicationContext 实现实例类型是什么。

Resource template = ctx.getResource("classpath:some/resource/path/myTemplate.txt");

也可以使用其他前缀

Resource template = ctx.getResource("file:///some/resource/path/myTemplate.txt");
Resource template = ctx.getResource("https://myhost.com/resource/path/myTemplate.txt");

getResource 字符串参数对象转换为资源对象的策略

资源前缀 示例 说明
classpath: classpath:com/myapp/config.xml 从 classpath 类路径加载
file: file:///data/config.xml 从文件系统中作为 URL 加载
http: https://myserver/logo.png 作为 URL 加载
(none) /data/config.xml 根据 ApplicationContext 实现实例加载

ResourceLoaderAware

ResourceLoaderAware 接口是一个特殊的回调接口,通过对应的 ApplicationContext 注入。

public interface ResourceLoaderAware {
void setResourceLoader(ResourceLoader resourceLoader);
}

当一个类实现 ResourceLoaderAware 接口时,Spring IoC 容器在加载该 bean 的时候将该 bean 类型识别为 ResourceLoaderAware 然后调用对应的 setResourceLoader(ResourceLoader resourceLoader) 方法并将 ApplicationContext 的实例的 getResource 方法返回实例传递进去

ApplicationContext 构建

ApplicationContext 的构建通常将字符串或字符串数组作为资源的位置路径。当字符串参数路径没有前缀时,加载 bean 的 Resource 实例依赖于 ApplicationContext 的实例。例如,考虑下面的例子,它创建了一个 ClassPathXmlApplicationContext:

ApplicationContext ctx = new ClassPathXmlApplicationContext("conf/appContext.xml");

appContext.xml 文件里的 bean 都是从类路径加载的,因为使用了 Classpathresource。

ApplicationContext 构建的通配符

构建 ApplicationContext 的参数路径可以是精确的路径 classpath:conf/appContext.xml 每个路径都有到目标资源的一对一映射。或者也可以包含特殊的字符 classpath*: 这种机制的一个用途是,当您需要进行依赖式的应用程序组装时。并且当使用以classpath*: 作为前缀的相同路径创建最终的 ApplicationContext 时,所有依赖包 classpath 都会自动被获取。

classpath 和 classpath* 区别

  1. classpath:用于加载类路径(包括jar包)中的一个且仅一个资源;对于多个匹配的也只返回一个。
  2. classpath* :用于加载类路径(包括jar包)中的所有匹配的资源。

注意:用 classpath*: 需要遍历所有的 classpath,所以加载效率会比较差一些尽量少使用。

Spring 学习笔记 Resource 资源的更多相关文章

  1. Spring学习笔记(1)——资源加载

    <!-- 占坑,迟点补充底层原理 --> Spring支持4种资源的地址前缀 (1)从类路径中加载资源——classpath: classpath:和classpath:/是等价的,都是相 ...

  2. Spring学习笔记及资源

    极客学院团队出品 Spring 教程  http://wiki.jikexueyuan.com/project/spring/ Spring 提供了以下两种不同类型的容器. 序号 容器 & 描 ...

  3. Spring学习笔记(一)

    Spring学习笔记(一) 这是一个沉淀的过程,大概第一次接触Spring是在去年的这个时候,当初在实训,初次接触Java web,直接学习SSM框架(当是Servlet都没有学),于是,养成了一个很 ...

  4. 不错的Spring学习笔记(转)

    Spring学习笔记(1)----简单的实例 ---------------------------------   首先需要准备Spring包,可从官方网站上下载.   下载解压后,必须的两个包是s ...

  5. Spring学习笔记(六)—— SSH整合

    一.整合原理 二.整合步骤 2.1 导包 [hibernate] hibernate/lib/required hibernate/lib/jpa 数据库驱动 [struts2] struts-bla ...

  6. Spring学习笔记之依赖的注解(2)

    Spring学习笔记之依赖的注解(2) 1.0 注解,不能单独存在,是Java中的一种类型 1.1 写注解 1.2 注解反射 2.0 spring的注解 spring的 @Controller@Com ...

  7. 【Spring学习笔记-MVC-3.1】SpringMVC返回Json数据-方式1-扩展

    <Spring学习笔记-MVC>系列文章,讲解返回json数据的文章共有3篇,分别为: [Spring学习笔记-MVC-3]SpringMVC返回Json数据-方式1:http://www ...

  8. spring学习笔记(一) Spring概述

    博主Spring学习笔记整理大部分内容来自Spring实战(第四版)这本书.  强烈建议新手购入或者需要电子书的留言. 在学习Spring之前,我们要了解这么几个问题:什么是Spring?Spring ...

  9. Java框架spring 学习笔记(十八):事务管理(xml配置文件管理)

    在Java框架spring 学习笔记(十八):事务操作中,有一个问题: package cn.service; import cn.dao.OrderDao; public class OrderSe ...

随机推荐

  1. MVC路由解析---MapRoute

    文章引导 MVC路由解析---IgnoreRoute MVC路由解析---MapRoute MVC路由解析---UrlRoutingModule Area的使用 引言 前面我们讲了IgnoreRout ...

  2. 6. 使用cadvisor监控docker容器

    Prometheus监控docker容器运行状态,我们用到cadvisor服务,cadvisor我们这里也采用docker方式直接运行.这里我们可以服务端和客户端都使用cadvisor 客户端 1.下 ...

  3. 如何在vim中同时编辑多个文件

    参考:http://stackoverflow.com/a/53668/941650 Why not use tabs (introduced in Vim 7)? You can switch be ...

  4. mysql与navicat应用

    下载安装配置 用法 1.连接本机数据库: 打开navicat选择连接---第一个mysql---在常规下自己明明连接名和密码----确定 我这边建立了本机测试库 2. 连接阿里云服务器上的mysql ...

  5. 深入了解line-height(各种单位总结1.5/150%/1.5em)

    默认状态,浏览器使用1.0-1.2 line-height, 这是一个初始值.你可以定义line-height属性来覆盖初始值:p{line-height:140%} 你可以有5种方式来定义line- ...

  6. Linux常用信号快捷键的使用

    ctrl-c 发送 SIGINT 信号给前台进程组中的所有进程.常用于终止正在运行的程序.ctrl-z 发送 SIGTSTP 信号给前台进程组中的所有进程,常用于挂起一个进程.ctrl-d 不是发送信 ...

  7. url传送图片的base64编码给web客户端

    base64编码图片: #python3.6 import base64 with open("./aa.jpg", "rb") as f: data = ba ...

  8. [python3]未配置locale的主机出现UnicodeDecodeError: 'ascii' codec can't decode byte 0x....的解决

    之前写的发邮件的程序部署到vps的时候出现了 UnicodeDecodeError: 'ascii' codec can't decode byte 0x.... 的错误. 按理说UnicodeDec ...

  9. 让所有Excel数据格全部乘 某个数

    1  首先设置单元格格式要是数字 2  然后在随便一个单元格写入你要乘的数字 3  粘贴的时候设置选择性粘贴,然后设置乘就OK

  10. ubuntu批量转换所有子文件夹下图片文件格式

    第一步按照 sudo apt-get install imagemagick 对于一个文件,可以: convert ubuntuhandbook.png ubuntuhandbook.jpg 对于多个 ...