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源码深度解析-------郝佳著。


相关文章
|
3天前
|
搜索推荐 JavaScript Java
基于springboot的儿童家长教育能力提升学习系统
本系统聚焦儿童家长教育能力提升,针对家庭教育中理念混乱、时间不足、个性化服务缺失等问题,构建科学、系统、个性化的在线学习平台。融合Spring Boot、Vue等先进技术,整合优质教育资源,提供高效便捷的学习路径,助力家长掌握科学育儿方法,促进儿童全面健康发展,推动家庭和谐与社会进步。
|
7月前
|
监控 Java 应用服务中间件
微服务——SpringBoot使用归纳——为什么学习Spring Boot
本文主要探讨为什么学习Spring Boot。从Spring官方定位来看,Spring Boot旨在快速启动和运行项目,简化配置与编码。其优点包括:1) 良好的基因,继承了Spring框架的优点;2) 简化编码,通过starter依赖减少手动配置;3) 简化配置,采用Java Config方式替代繁琐的XML配置;4) 简化部署,内嵌Tomcat支持一键式启动;5) 简化监控,提供运行期性能参数获取功能。此外,从未来发展趋势看,微服务架构逐渐成为主流,而Spring Boot作为官方推荐技术,与Spring Cloud配合使用,将成为未来发展的重要方向。
220 0
微服务——SpringBoot使用归纳——为什么学习Spring Boot
|
4月前
|
安全 Java 数据库
Spring Boot 框架深入学习示例教程详解
本教程深入讲解Spring Boot框架,先介绍其基础概念与优势,如自动配置、独立运行等。通过搭建项目、配置数据库等步骤展示技术方案,并结合RESTful API开发实例帮助学习。内容涵盖环境搭建、核心组件应用(Spring MVC、Spring Data JPA、Spring Security)及示例项目——在线书店系统,助你掌握Spring Boot开发全流程。代码资源可从[链接](https://pan.quark.cn/s/14fcf913bae6)获取。
511 2
|
6月前
|
Java Spring
Spring框架的学习与应用
总的来说,Spring框架是Java开发中的一把强大的工具。通过理解其核心概念,通过实践来学习和掌握,你可以充分利用Spring框架的强大功能,提高你的开发效率和代码质量。
152 20
|
12月前
|
Java Maven Spring
springboot学习一:idea社区版本创建springboot项目的三种方式(第三种为主)
这篇文章介绍了在IntelliJ IDEA社区版中创建Spring Boot项目的三种方法,特别强调了第三种方法的详细步骤。
9609 0
springboot学习一:idea社区版本创建springboot项目的三种方式(第三种为主)
|
11月前
|
前端开发 Java 开发者
Spring生态学习路径与源码深度探讨
【11月更文挑战第13天】Spring框架作为Java企业级开发中的核心框架,其丰富的生态系统和强大的功能吸引了无数开发者的关注。学习Spring生态不仅仅是掌握Spring Framework本身,更需要深入理解其周边组件和工具,以及源码的底层实现逻辑。本文将从Spring生态的学习路径入手,详细探讨如何系统地学习Spring,并深入解析各个重点的底层实现逻辑。
235 9
|
数据采集 监控 Java
SpringBoot日志全方位超详细手把手教程,零基础可学习 日志如何配置及SLF4J的使用......
本文是关于SpringBoot日志的详细教程,涵盖日志的定义、用途、SLF4J框架的使用、日志级别、持久化、文件分割及格式配置等内容。
755 2
SpringBoot日志全方位超详细手把手教程,零基础可学习 日志如何配置及SLF4J的使用......
|
存储 开发框架 Java
什么是Spring?什么是IOC?什么是DI?IOC和DI的关系? —— 零基础可无压力学习,带源码
文章详细介绍了Spring、IOC、DI的概念和关系,解释了控制反转(IOC)和依赖注入(DI)的原理,并提供了IOC的代码示例,阐述了Spring框架作为IOC容器的应用。
764 1
什么是Spring?什么是IOC?什么是DI?IOC和DI的关系? —— 零基础可无压力学习,带源码
|
12月前
|
前端开发 Java 数据库
SpringBoot学习
【10月更文挑战第7天】Spring学习
148 9
|
12月前
|
XML Java 数据格式
Spring学习
【10月更文挑战第6天】Spring学习
95 1