Spring学习之资源管理器(Resource)

简介: 今天开始Spring学习(希望发展的是Spring的源码学习的系列)的第一章。 资源的抽象接口(Resource) 我们在用Spring做开发的时候,总免不了读取各种各样的资源文件,比如说Spring的xml配置文件、属性的配置文件properties文件等。

今天开始Spring学习(希望发展的是Spring的源码学习的系列)的第一章。

资源的抽象接口(Resource)

我们在用Spring做开发的时候,总免不了读取各种各样的资源文件,比如说Spring的xml配置文件、属性的配置文件properties文件等。这些资源文件可能在classPath下面、web容器的上下文中、网络上等等。虽然JDK将不同来源的资源抽象成URL,通过注册不同的handler(URLStreamHandler)来处理不同来源的资源的读取逻辑(根据使用的不同协议来识别这些资源文件的来源,像“file:”、“http:”、“jar:”),但是URL没有默认定义相对ClassPath或ServletContext等资源的handler,即便我们可以注册自己的URLStreamHandler来解析特定的URL前缀(协议如classpath:),但是这需要我们了解URL的实现机制,要求比较高,并且URL也没有提供一些基本的方法,比如检查当前资源是否存在,检查当前资源是否可读等。所以,Spring为了处理不同的资源类型抽象了一个接口出来,这个接口是Resource。我们先来看一下Resource的相关类图:


接下来我们看一下Resource中为我们提供了那些方法:

exists 资源是否存在
isReadable 资源是否可读
isOpen 资源是否打开
getURL 如果底层资源可以表示成URL,该方法返回对应的URL对象
getURI 如果底层资源可以表示成URI,该方法返回对应的URI对象
getFile 如果底层资源对应的是一个文件,该方法返回一个File对象
contentLength 返回资源的内容长度
lastModified 返回资源的最后修改时间
createRelative 在资源相对地址上创建文件
getFilename 返回文件的名字
getDescription 错误处理中打印出来的信息
接着我们看一下Resource的主要的一些实现类的作用:

ByteArrayResource 表示的是二进制数组的资源,二进制数组的资源可以通过程序在内存中构造(还记得IO中的ByteArrayInputStream吗)
ClassPathResource 类路径下的资源,即资源以相对于类路径的方式表示
FileSystemResource 文件系统资源,资源以文件系统路径的方式表示(例如:D:/spring/conf.xml)
InputStreamResource 表示的是InputStream的资源
ServletContextResource 为访问Web容器上下文中的资源而设计的类,负责以相对于Web应用根目录的路径加载资源,它支持以流和URL的方式
访问,在WAR解包的情况下,也可以通过File的方式访问,该类还可以直接从JAR包中访问资源。
UrlResource 封装了java.net.URL,它使用户能够访问任何可以通过URL表示的资源,如文件系统的资源、HTTP资源、FRP资源等.
PathResource 表示的是一个NIO形式的资源
假设现在有一个资源在Web应用的类路径下,我们可以有几种方式来访问这个资源呢?

  1. 通过FileSystemResource以文件系统绝对路径的方式进行访问(如:D:/spring/WebRoot/WEB-INF/classes/conf.xml)
  2. 通过ClassPathResource以类路径的方式进行访问(如:conf.xml)
  3. 通过ServletContextResource以相对于Web应用根目录的方式进行访问(如:ServletContextResource(ServletContext,"/WEB-INF/classes/conf.xml”))可以通过ContextLoader.getCurrentWebApplicationContext().getServletContext()来获取ServletContext
为了访问不同类型的资源,Spring为我们提供了相应的Resource的实现类,但是我们使用这些Resource的实现类的时候呢都是直接实例化相应的实例,那么有没有一种方式通过一些特殊的标识(像URL中的"file:"、"jar:")来加载相应的资源呢,想象一下我们在web.xml中配置的资源路径,在Spring的配置文件写的import。很明显的Spring为我们提供了这样的资源加载机制。

资源加载

我们来看一下Spring为我们提供了哪些资源类型的地址前缀:
地址前缀 示例 对应的资源类型
classpath: classpath:com/spring/conf.xml 从类路径总加载资源,classpath:和classpath:/是等价的,都是相对于类的根路径。资源文件
可以在标准的文件系统中,也可以在jar或zip的类包中
file: file:/com/spring/conf.xml 使用UrlResource从文件系统目录中装载资源,可以使用绝对或相对路径
http:// http://www.xxx.conf.xml 使用UrlResource从web服务器中装载资源
ftp:// ftp://www.xxx.conf.xml 使用UrlResource从FTP服务器中装载资源
没有前缀 com/spring/conf.xml 根据ApplicationContext具体实现类采用对应类型的Resource

classpath:和classpath*:

我们可能经常在项目中看到classpath:和classpath*:这两种的地址前缀,这两种地址前缀有什么区别呢?classpath:只会从第一个加载的com.spring包下查找,而classpath*:则会扫描所有的com.spring包,不管是在jar中还是项目中的。这样就明白了吧。通用我们在写资源配置路径的时候还可以用Ant风格,如:
  1. ?:匹配文件名中的一个字符
  2. *:匹配文件名中任意个字符
  3. **:匹配多层路径
我们来看几个示例:
示例 说明
classpath:com/t?st.xml 匹配com包路径下com/test.xml、com/tast.xml等
file:D:/conf/*.xml 匹配文件系统D:/conf目录下所有以xml为后缀的文件
classpath:com/**/text.xml 匹配com包路径下(当前目录及其子孙目录)的test.xml
classpath:org/spring/**/*.xml 匹配类路径org/spring下所有以xml为后缀的文件
classpath:org/**/servlet/con.xml 匹配类路径org/spring/servlet/conf.xml、org/spring/test/servlet/con.xml
还匹配org/servlet/con.xml

资源加载器

资源加载器的父接口是ResourceLoader接口,这个接口只有一个getResource(String location)的方法,可以根据一个资源地址加载文件,它只支持带资源类型前缀的表达式,不支持Ant风格的资源路径表达式。有一个ResourcePatternResolver扩展ResourceLoader接口,定义了一个新的接口:getResources(String locationPattern),该方法支持带资源类型前缀及Ant风格的资源路径的表达式。PathMatchingResourcePatternResolver是Spring提供的一个标准的实现。我们用到的其他的获取Bean的类,都是用到了这个PathMatchingResourcePatternResolver类。我们看一下根据ResourceLoader画出来的一个类图,包含了很多IOC核心的类。

参考摘录自:

Spring 3.x 企业应用开发实战 ----------陈雄华 林开雄著。

Spring源码深度解析-------郝佳著。


相关文章
|
5月前
|
Java 数据库 Spring
【Spring】资源操作管理:Resource、ResourceLoader、ResourceLoaderAware;
【Spring】资源操作管理:Resource、ResourceLoader、ResourceLoaderAware;
53 1
|
7月前
|
Java 测试技术 Docker
Spring Boot 学习研究笔记(十九)-docker部署SpringBoot 日志目录挂载
Spring Boot 学习研究笔记(十九)-docker部署SpringBoot 日志目录挂载
273 0
|
9天前
|
Java 数据安全/隐私保护 Sentinel
微服务学习 | Spring Cloud 中使用 Sentinel 实现服务限流
微服务学习 | Spring Cloud 中使用 Sentinel 实现服务限流
|
10天前
|
Java Nacos 开发者
Java从入门到精通:4.2.1学习新技术与框架——以Spring Boot和Spring Cloud Alibaba为例
Java从入门到精通:4.2.1学习新技术与框架——以Spring Boot和Spring Cloud Alibaba为例
|
10天前
|
Dubbo Java 应用服务中间件
Java从入门到精通:3.2.2分布式与并发编程——了解分布式系统的基本概念,学习使用Dubbo、Spring Cloud等分布式框架
Java从入门到精通:3.2.2分布式与并发编程——了解分布式系统的基本概念,学习使用Dubbo、Spring Cloud等分布式框架
|
3月前
|
安全 Java 开发者
Spring依赖注入大揭秘:@Autowired、@Qualifier和@Resource的区别与应用
Spring依赖注入大揭秘:@Autowired、@Qualifier和@Resource的区别与应用
63 0
|
3月前
|
Java 调度 开发工具
SpringCloud【微服务架构进化论、微服务的拆分规范和原则、为什么选择Spring Cloud、什么是服务治理 】(一)-全面详解(学习总结---从入门到深化)
SpringCloud【微服务架构进化论、微服务的拆分规范和原则、为什么选择Spring Cloud、什么是服务治理 】(一)-全面详解(学习总结---从入门到深化)
191 0
|
4月前
|
Java Spring
spring注解@Autowired、@Resource说明
spring注解@Autowired、@Resource说明
|
5月前
|
Java 编译器 Spring
Spring中@Autowired和@Resource的区别
Spring中@Autowired和@Resource的区别
111 0
|
5月前
|
Java Spring 容器
[Spring] 字节一面~Spring 如何解决循环依赖问题 以及 @resource 与 @autowire 同时存在时谁生效
[Spring] 字节一面~Spring 如何解决循环依赖问题 以及 @resource 与 @autowire 同时存在时谁生效