Spring 学习笔记 Resource 资源
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;
}
方法解析:
- getInputStream():每次调用都会返回一个与资源对应的 InputStream 字节流,调用者有必要在使用后关闭该资源。
- exists():返回 true 表示当前资源存在。
- isOpen():返回 Resource 代表的资源是否已经被打开。如果返回 true,则只能读取一次不能多次读取 InputStream,然后关闭,以避免资源泄漏。对于所有常见的 Resource 实现一般返回 false。
- getURL():返回 Resource 代表资源对应的 java.util.URL 对象。
- getFile():返回 Resource 代表资源对应的 java.io.File 对象。
- createRelative(String relativePath):用于创建相对于当前 Resource 代表资源的资源,比如当前 Resource 代表文件资源 “d:/test/” 则 createRelative(“test.txt”) 将返回表文件资源 “d:/test/test.txt” Resource 资源。
- getFilename():返回 Resource 代表资源对应的文件路径。
- getDescription():返回 Resource 代表资源的描述符,通常就是资源的全路径(实际文件名或实际 URL 地址)。
Spring 框架自身就非常广泛使用 Resource,在我们的项目中也可以使用并且可以非常方便的获取到目标资源。
内置 Resource 接口实现
- UrlResource
- ClassPathResource
- FileSystemResource
- ServletContextResource
- InputStreamResource
- ByteArrayResource
UrlResource
UrlResource 封装了 java.net.URL,可用于访问通过 URL 访问的任何对象,比如文件、HTTP 资源、FTP 资源等等。所有 URL 都有一个标准化的字符串表示,因此可以使用适当的标准化前缀来表示不同 URL 类型的 URL。一般支持如下资源访问。
- file:用于访问文件系统路径
new UrlResource("file:d/xxx.txt");
- http:用于通过 http 协议访问资源
new UrlResource("http://地址");
- 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);
- public ClassPathResource(String path):使用默认的类加载器记载 path 类路径下的资源
- public ClassPathResource(String path, @Nullable ClassLoader classLoader):使用指定的类加载器加载 path 类路径下的资源
- 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
- ClassPathXmlApplicationContext
- FileSystemXmlApplicationContext
- 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* 区别
- classpath:用于加载类路径(包括jar包)中的一个且仅一个资源;对于多个匹配的也只返回一个。
- classpath* :用于加载类路径(包括jar包)中的所有匹配的资源。
注意:用 classpath*: 需要遍历所有的 classpath,所以加载效率会比较差一些尽量少使用。
Spring 学习笔记 Resource 资源的更多相关文章
- Spring学习笔记(1)——资源加载
<!-- 占坑,迟点补充底层原理 --> Spring支持4种资源的地址前缀 (1)从类路径中加载资源——classpath: classpath:和classpath:/是等价的,都是相 ...
- Spring学习笔记及资源
极客学院团队出品 Spring 教程 http://wiki.jikexueyuan.com/project/spring/ Spring 提供了以下两种不同类型的容器. 序号 容器 & 描 ...
- Spring学习笔记(一)
Spring学习笔记(一) 这是一个沉淀的过程,大概第一次接触Spring是在去年的这个时候,当初在实训,初次接触Java web,直接学习SSM框架(当是Servlet都没有学),于是,养成了一个很 ...
- 不错的Spring学习笔记(转)
Spring学习笔记(1)----简单的实例 --------------------------------- 首先需要准备Spring包,可从官方网站上下载. 下载解压后,必须的两个包是s ...
- Spring学习笔记(六)—— SSH整合
一.整合原理 二.整合步骤 2.1 导包 [hibernate] hibernate/lib/required hibernate/lib/jpa 数据库驱动 [struts2] struts-bla ...
- Spring学习笔记之依赖的注解(2)
Spring学习笔记之依赖的注解(2) 1.0 注解,不能单独存在,是Java中的一种类型 1.1 写注解 1.2 注解反射 2.0 spring的注解 spring的 @Controller@Com ...
- 【Spring学习笔记-MVC-3.1】SpringMVC返回Json数据-方式1-扩展
<Spring学习笔记-MVC>系列文章,讲解返回json数据的文章共有3篇,分别为: [Spring学习笔记-MVC-3]SpringMVC返回Json数据-方式1:http://www ...
- spring学习笔记(一) Spring概述
博主Spring学习笔记整理大部分内容来自Spring实战(第四版)这本书. 强烈建议新手购入或者需要电子书的留言. 在学习Spring之前,我们要了解这么几个问题:什么是Spring?Spring ...
- Java框架spring 学习笔记(十八):事务管理(xml配置文件管理)
在Java框架spring 学习笔记(十八):事务操作中,有一个问题: package cn.service; import cn.dao.OrderDao; public class OrderSe ...
随机推荐
- (13)C++ 多态
虚析构和纯虚析构用来解决父类指针释放子类对象的问题,此时会不调用子类的析构函数 如果子类没有堆数据,可以不使用虚析构
- Java 空字符串和 字符串为null的区别
之前一直没有搞清楚 字符串为空和字符串为null的区别,今天写代码一直出现NullPointerException异常,我一直没有搞清楚,后来发现我是这样写的 String s = null; s = ...
- Micro SQL Server2016
Microsoft SQL Server 2016 序列号(中英文通用) SQL Server 2016 企业版: MDCJV-3YX8N-WG89M-KV443-G8249SQL Server 2 ...
- 解决vcenter 6.0 vcsa安装插件第二个的时候报错的问题
解决vcenter 6.0 vcsa安装插件第二个的时候报错的问题 需要打一下windows 的Microsoft v C++ 2013的2个补丁就可以正常运行了. 然后在后续安装过程中,到达最后一步 ...
- Translucent System Bar 的最佳实践
转自:http://www.jianshu.com/p/0acc12c29c1b 近几天准备抽空总结Android一些系统UI的实践使用,于是开始动手建了一个库 AndroidSystemUiTrai ...
- C++中创建对象的时候加括号和不加括号的区别(转)
c++创建对象的语法有----- 1 在栈上创建 MyClass a; 2 在堆上创建加括号 MyClass *a= new MyClass(); 3 不加括号 MyClass *a = new My ...
- C++中的delete加深认识
delete操作: 我们在删除一个指针之后,编译器只会释放该指针所指向的内存空间,而不会删除这个指针本身. 1.假如你不去释放,那么该区域的内存始终不能被其他数据所使用.2.指向该内存的指针是个局部变 ...
- CSP 初赛复习 密码
CSP 初赛复习 密码是\(xj\)机房学生端密码
- 高性能js之js文件的加载与解析
随着网站的发展,现在的网页已经离不开js,经常一个页面会引入大量的js.那么该如何合理的加载这些js? head标签中引入js文件可能是最常见的一种方式,但是这样会造成一个问题.因为j可以说是浏览器中 ...
- 【JavaWeb项目】一个众筹网站的开发(四)后台用户注册功能
重点: 密码加密存储 使用jQuery插件做校验和错误提示等 密码不能明文存储,在数据库中是加密存储的 可逆加密:通过密文使用解密算法得到明文 DES AES 不可逆加密:通过密文,得不到明文 MD5 ...