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. AJAX请求,返回json进行页面绑值

    AJAX请求,返回json进行页面绑值 后台 controller @RequestMapping(value = "backjson.do",method=RequestMeth ...

  2. PicoCTF 2013 Dark Star 分析

    0x00题目 题目可以从GitHub中找到:https://github.com/picoCTF/2013-Problems/blob/master/Dark%20Star/darkstar.img ...

  3. 2019 ACM-ICPC 南京 现场赛 H. Prince and Princess

    题意 王子想要娶公主,但是需要完成一个挑战:在一些房间中找出公主在哪. 每个房间有一个人,他们彼此知道谁在哪个房间.可以问他们三种问题: 你是谁? 在某个房间是谁? 公主在哪个房间? 有三类人,一类一 ...

  4. 嵌入式C语言4.4 C语言内存空间的使用-多级指针

    多级指针 int **p; 存访地址的地址空间

  5. Linux 常用指令总结

    一. 与时间有关的参数: 1.find 基本语法参数如下: find [PATH] [option] [action] -mtime n : n为数字,意思为在n天之前的“一天内”被更改过的文件: - ...

  6. Linux(四)—— 项目部署与ansible自动化部署

    目录 项目部署与ansible自动化部署 一.项目部署 二.ansible自动化部署(python自动化运维) 1.安装ansible 2.ansible例子 3.ansible自动化部署nginx ...

  7. 安装项目依赖pipreqs并生成requirements.txt

    安装项目依赖:sudo pip3 install pipreqs 生成依赖文件(requirements.txt):pipreqs ./   # 进入项目目录,在项目文件夹里生成安装依赖文件里的环境: ...

  8. VC2008中如何为MFC应用程序添加和删除消息响应函数

    最近重温<MFC Windows应用程序设计>第二版这本书,里面的代码全部是使用VC6.0写的,我Win7下安装的是VS2008开发环境. VC2008下添加和删除常见的消息响应函数有两种 ...

  9. 在Ubuntu下安装deb包需要使用dpkg命令

    Dpkg 的普通用法: 1.sudo dpkg -i <package.deb> 安装一个 Debian 软件包,如你手动下载的文件. 2.sudo dpkg -c <package ...

  10. offset 、 client 和 scroll - PC端网页特效

    1.元素偏移量  offset 系列 1.1 offset 就是偏移量,使用 offset 系列相关属性可以 动态 得到该元素的位置(偏移).大小等. 注意: 1.获得元素距离带有定位父元素的位置 2 ...