撸一撸Spring Framework-IoC-资源管理利器(Resource、ResourceLoader、ResourcePatternResolver)

article/2025/9/18 18:58:32

   撸一撸Spring Framework-IoC系列文章目录

  • IoC概述
  • BeanFactory
  • ApplicationContext
  • BeanDefinition
  • BeanWrapper
  • 资源管理利器(Resource与ResourceLoader)
  • 配置管理(Environment与PropertySource)
  • 实现通用功能的利器(PostProcessor机制)

我们经常需要读取外部资源到应用中,比如文本文件、properties文件、图片文件等。这些资源可能位于不同的位置,比如文件系统、classpath下的资源、或者远程服务器上的资源。通常,我们需要通过不同的API分别加载不同类型路径的资源,有诸多不便之处 

 Spring提供了Resource系列接口解决上述问题,API非常友好、强大

Resource:是对诸如文件系统资源、classpath资源、URL资源等各种资源的抽象

ResourceLoader:提供了统一的加载Resource的方法,它通过资源路径前缀自动匹配相应的资源类型,为开发者屏蔽了使用不同Resource实现的差异

ResourcePatternResolver:比ResourceLoader更强大,支持以通配符的方式加载所有满足条件的资源

Spring内部就通过Resource系列接口进行资源加载,比如我们定义的xml文件、properties文件、@ComponentScan扫描的java类文件等,都是通过这套接口进行加载的

除此之外,Resource相关接口可以脱离Spring独立使用,我们可以通过如下方式加载不同类型资源:

//资源加载器(ResourceLoader接口的默认实现类)
ResourceLoader resourceLoader=new DefaultResourceLoader();
//通过指定不同前缀的资源路径,加载不同类型的资源
//通过文件系统绝对路径加载资源
Resource resource = resourceLoader.getResource("file:D:/code/spring/src/main/resources/demo.xml");
//通过相对于当前项目根目录的相对路径加载资源
Resource resource = resourceLoader.getResource("file:src/main/resources/demo.xml");
//加载classpath下的资源
Resource resource = resourceLoader.getResource("classpath:demo.xml");
Resource resource = resourceLoader.getResource("classpath:com/example/spring/ResourceLoaderDemo.class");
//通过https url加载CSDN上的一篇博客资源  
Resource resource = resourceLoader.getResource("https://blog.csdn.net/wb_snail/article/details/108134550");
(tips:按通配符加载一组资源的方式,下文会有说明)

拿到Resource后,可以调用Resource#getInputStream获取资源输入流,读取其内容:

InputStream inputStream=resource.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
while (true) {String line = reader.readLine();if (line == null)break; System.out.println(line);
} 
reader.close();

如果你想通过与Spring集成的方式使用ResourceLoader,可以这样操作:

1、实现ResourceLoaderAware接口,Spring容器启动过程中回调注入ResourceLoader实例

2、@Autowired ResourceLoader resourceLoader(Spring容器启动过程中,会向BeanFactory中注入一些特殊的对象(包括ResourceLoader对象 ),特殊是因为它们没有被定义为bean,它们是spring内部的组件,spring允许我们通过@Autowire来使用它们)

3、使用ApplicationContext,ApplicationContext继承于ResourceLoader,实际上通过前两种方式拿到的ResourceLoader对象,就是ApplicationContext(默认情况下,由于AbstractApplicationContext继承于DefaultResourceLoader,使用ApplicationContext进行资源加载时,最终还是会由DefaultResourceLoader执行)

Resource接口比较核心的方法有:

getInputStream():继承于InputStreamSource接口,返回资源对应的输入流,用于读取资源

exists():返回资源是否存在的标识

getFile():如果资源存在于文件系统中,返回对应的文件对象,否则抛出FileNotFoundException(比如ByteArrayResource这种只在内存中存在的资源)

getURL():返回资源对应的URL(java.net.URL),URL是资源定位符,上述例子中的"file:D:/demo.xml"、"classpath:demo.xml"、"https://blog.csdn.net/wb_snail/article/details/108134550"都是URL的String表示形式

Resource继承体系如下(体系比较大,这里只挑选了一些比较常见的Resource实现):

InputStreamSource:Resource的父接口,只有一个getInputStream()方法

WritableResource:可写资源,它的方法getOutputStream()可以返回资源的输出流

FileSystemResource:文件系统资源,可通过File对象、文件系统绝对路径、Path对象(如Paths.get("D:/demo.xml"))来构建(tips:Spring在处理@ComponentScan定义的包路径下的class文件时,会将它们加载为FileSystemResource)

ClassPathResource:classpath下的资源(tips:Spring在处理@PropertyResource、@PropertyResources时,相关配置文件会被加载为ClassPathResource)

UrlResource:引用了一个java.net.URL对象,可以访问任何可以用URL表示的资源(file、https、ftp等资源)

ServletContextResource:web应用资源,资源路径以相对于web应用根目录的路径表示,比如new ServletContextResource("/WEB-INF/demo.xml")

ByteArrayResource:通过一个二进制数组创建的资源,比如new ByteArrayResource(new String("hello").getBytes(StandardCharsets.UTF_8))

Resource几乎可以表示任何类型的底层资源,除了Spring已经实现的多种资源类型外,你还可以实现自己的Resource(比如DB中的资源),你可以向ResourceLoader中注册一个ProtocolResolver,然后就可以使用ResourceLoader以与其他类型资源无差别的方式加载你的资源。相关源码如下

public class CustomResource {public static void main(String[] args) {DefaultResourceLoader resourceLoader=new DefaultResourceLoader();//注册自定义ProtocolResolverresourceLoader.addProtocolResolver(new DbProtocolResolver());//通过"db:"为前缀的路径加载db中的资源Resource dbResource=resourceLoader.getResource("db:dataSource_fileDB/table_file/column_content");}
}//自定义Resource
public class DbResource extends AbstractResource {private final String path;...
}/*** 实现ProtocolResolver,针对前缀为"db:"的url,返回DBResource*/
public class DbProtocolResolver implements ProtocolResolver {private static final String DB_URL_PREFIX="db:";@Nullablepublic Resource resolve(String location, ResourceLoader resourceLoader){if(location.startsWith(DB_URL_PREFIX)){return new DbResource(location.substring(DB_URL_PREFIX.length()));}return null;}
}//以下是DefaultResourceLoader中相关部分的源码
public class DefaultResourceLoader implements ResourceLoader {//一组ProtocolResolver实例private final Set<ProtocolResolver> protocolResolvers = new LinkedHashSet<>(4);public DefaultResourceLoader() {}//调用该方法,注册你自定义的ProtocolResolverpublic void addProtocolResolver(ProtocolResolver resolver) {Assert.notNull(resolver, "ProtocolResolver must not be null");this.protocolResolvers.add(resolver);}@Overridepublic Resource getResource(String location) {Assert.notNull(location, "Location must not be null");//加载资源时,优先通过你注册的ProtocolResolver加载资源for (ProtocolResolver protocolResolver : getProtocolResolvers()) {Resource resource = protocolResolver.resolve(location, this);if (resource != null) {return resource;}}if (location.startsWith("/")) {return getResourceByPath(location);}else if (location.startsWith(CLASSPATH_URL_PREFIX)) {return new ClassPathResource(location.substring(CLASSPATH_URL_PREFIX.length()), getClassLoader());}else {try {// Try to parse the location as a URL...URL url = new URL(location);return (ResourceUtils.isFileURL(url) ? new FileUrlResource(url) : new UrlResource(url));}catch (MalformedURLException ex) {// No URL -> resolve as resource path.return getResourceByPath(location);}}}
}

ResourceLoader仅支持匹配单个资源,其扩展接口ResourcePatternResolver支持以通配符的方式加载所有满足条件的资源,比如"classpath*:META-INF/spring.handlers"、"classpath:META-INF/*.properties"、"/WEB-INF/*-context.xml"、"file:D:/resources/*.properties"

注意"classpath:"和"classpath*:"的区别,后者会把classpath下所有jar包也作为查找目标,@ComponentScan可以扫描jar包下的@Component,正是利用了这个特性,Spring通过查找spring.handlers文件实现SPI也是一样道理

ResourcePatternResolver支持三种通配符:

*:匹配资源路径中的任意字符

?:匹配资源路径中的单个字符

如"*.xml"可以匹配到a.xml、ab.xml,而"?.xml"只能匹配到a.xml

**:匹配任意层级,比如"mapper/**/*Mapper.xml"可以匹配到mapper/RoleMapper.xml、mapper/order/OrderMapper.xml、mapper/order/goods/GoodsMapper.xml

Spring Framework中,ResourcePatternResolver的唯一有效实现是PathMatchingResourcePatternResolver,ApplicationContext也继承于ResourcePatternResolver,默认情况下,其getResources方法会委托给PathMatchingResourcePatternResolver执行

可以通过两种方式使用ResourcePatternResolver的能力 :

//使用PathMatchingResourcePatternResolver加载
ResourcePatternResolver resourcePatternResolver=new PathMatchingResourcePatternResolver();
Resource[] resources=resourcePatternResolver.getResources("classpath*:META-INF/spring.handlers");//使用ApplicationContext加载
AnnotationConfigApplicationContext applicationContext=new AnnotationConfigApplicationContext();
applicationContext.refresh();
Resource[] resources=applicationContext.getResources("classpath*:META-INF/spring.handlers");
  • 和ResourceLoader一样,ResourcePatternResolver同样支持脱离Spring容器使用,通过直接new PathMatchingResourcePatternResolver()的方式使用非常方便
  • 默认情况下,ApplicationContext#getResources方法会委托给PathMatchingResourcePatternResolver执行,因此只要可以拿到ApplicationContext实例,也可以进行基于正则的批量资源加载

http://chatgpt.dhexx.cn/article/HZjyIM4E.shtml

相关文章

uni-app 资源在线升级/热更新

HBuilderX 1.6.5 起&#xff0c;uni-app 支持生成 App 资源升级包。 生成 App 资源升级包 修改版本号 首先&#xff0c;更新 manifest.json 中的版本号。 比如之前是 1.0.0&#xff0c;那么新版本应该是 1.0.1 或 1.1.0 这样。 发行 然后&#xff0c;在 HBuilderX 中生成升…

【有手就行】定制一个GIF表情

前言&#x1f447; 完成这个任务不需要安装任何编程软件&#xff0c;不需要任何基础&#xff0c;有手就行&#xff01; 效果图&#x1f447; &#xff08;御用素材&#x1f438;S先生&#xff09;&#x1f447; 制作步骤&#x1f447; ①登陆网址https://benisland.neocitie…

Squish 7.0中视频捕获 (含相关网络直播研讨会报名信息)

本文翻译自Video capture in Squish 7.0 – feature focus &#xff08;原文发布于2022年3月4日&#xff09; 原文作者&#xff1a;Qt公司软件工程师Katarina Behrens 翻译&#xff1a;Joyce Jiang Squish GUI Tester 7.0是首个提供独特新功能的Squish版本&#xff1a;通过捕获…

(一)squid简介

1、一些squid的概念 squid是一个缓存服务器的守护进程&#xff0c;其支持的代理协议&#xff1a;FTP,HTTP,SSL,套接字。 存储分类&#xff1a;磁盘>分区>目录>Object&#xff08;缓存文件&#xff09; 索引方式&#xff1a; Hash Tables 目录 每个Digest的索…

【深入UCSC Genome Brower】他山之石

转自&#xff1a;https://mp.weixin.qq.com/s?__bizMzAwMzY4MTYxNw&mid2655752921&idx1&sn159f79dde58d2145c59307e23a06b97a&scene0#wechat_redirect 这是一个神奇的网站&#xff1a;UCSC Genome Brower 有朋友在后台留言让介绍下UCSC Genome Browser&#x…

SWISH

①基础符号&#xff1a; :- 输出 \ 非 ②判断是否匹配文字备注 例1&#xff08;未匹配成功&#xff09; 例2&#xff08;输出a所在的list&#xff1a;N&#xff1f;&#xff09; 例3

Swish hard-Swish

当β = 0时,Swish变为线性函数f(x)=x/2 β → ∞, σ(x)=(1+exp(−x))−1σ(x)=(1+exp⁡(−x))−1为0或1. Swish变为ReLU: f(x)=2max(0,x) 所以Swish函数可以看做是介于线性函数与ReLU函数之间的平滑函数. beta是个常数或者可以训练的参数。其具有无上界有下界、平滑、非单调的…

Squid服务

Squid服务 一、Squid 服务基础 Squid 是 Linux 系 统 中 最 常 用 的 一 款 开 源 代 理 服 务 软 件 &#xff0c;可以很好地实现 HTTP 和 FTP&#xff0c;以及 DNS 查询、SSL 等应 用的缓存代理&#xff0c;功能十分强大。 官 方 网 站 为&#xff1a; http://www.squid-c…

Lua整合工具 squish使用方法

squish是一个开源的用于打包lua脚本的小工具&#xff0c;它的主要功能是将多个lua文件整合成一个文件&#xff0c;并在此基础上做压缩和混淆等处理&#xff0c;混淆和压缩后的代码可以直接被执行而不需要先做解压还原等操作。 它的github地址&#xff1a;https://github.com/L…

测试资深人士推荐的GUI跨平台自动化测试工具

Squish GUI 测试自动化工具使跨平台测试应用程序变得容易&#xff0c;它对Qt的支持非常好。 在发布应用程序之前测试用户界面比以往任何时候都更加重要&#xff0c;当今用户需要从移动、桌面、Web和嵌入式应用程序中获得无缝的跨平台体验。由于应用程序经常在工厂、汽车甚至厨…

难道真的有人因为要分享squish测试工具而去学习QT吗

1下载安装 1.去官网下载QT工具并安装&#xff0c;下载地址&#xff1a;https://download.qt.io/official_releases/qt/ &#xff1b;如下图选择自己想要下载的版本&#xff0c;我下载的5.12.12&#xff0c;文件3.7G&#xff0c;如图注册完成&#xff0c;全选完成&#xff0c;后…

UCSC 基因组浏览器配置详解

一、配置参数 UCSC基因组浏览器&#xff1a;传送门 1、点击配置 2、进入配置页面&#xff1a; 点击刚刚运行的文件 BedGraph Format 2、轨迹配置页面 Type of graph &#xff1a;默认以bar&#xff0c;条形图来显示&#xff0c;选择point会以点或线来显示Track height &…

Squish — 基于Qt的HMI自动化测试工具

目录 自动化测试方案设置Squish记录测试属性验证视觉验证总结 本文翻译自Squish - Test automation tool for our HMI build with Qt 原文作者&#xff1a;Piotr Lesiecki 校审&#xff1a;Kenny Zhang 当测试工程师们听到自动化测试时&#xff0c;首先会想到的一定是Selenium…

Squish - GUI Tester

Squish - GUI Tester Squish overview 网上查询关于自动化测试工具Squish的资料很少。特别是中文搜索。最近正好在使用这款工具&#xff0c;在使用中总结了一些知识&#xff0c;在这里和大家一起分享下。 Squish是froglogic公司的一款商业自动化工具&#xff0c;几年前好像是…

Squish for Qt:为Qt应用量身打造的自动化测试工具

转载地址&#xff1a;https://mp.weixin.qq.com/s?__bizMzI5MzA3NzU3OA&mid2649661399&idx1&sn7b584cfc54e529d6ce605274d8f7bc0b&chksmf46da8f2c31a21e4eccfe9ee0eb690045cdd8a074af0e57bceb8f605c5fcb2fb72c9d7334c28&mpshare1&scene1&srcid072…

基于GUI测试工具Squish的使用

转载自&#xff1a;http://www.readingday.cn/squish-for-qt-2/ 申请Squish试用 浏览器打开Squish官网&#xff08;https://www.froglogic.com/squish/free-trial/&#xff09;&#xff0c;填写试用申请表。您需要提供一个有效的邮箱地址&#xff0c;以便接收到Squish官方所发送…

浅析如何利用Squish实行 GUI自动化测试

1.引言 图形用户界面&#xff08;Graphical User Interface&#xff0c;简称 GUI&#xff0c;又称图形用户接口&#xff09;是指采用图形方式显示的系统操作用户界面。是软件与用户进行交互的主要方式&#xff0c;与早期计算机使用的命令行界面相比&#xff0c;图形界面对于用户…

关于Squish的介绍和简单使用说明

网络研讨会 | Squish for Qt: 为Qt应用量身打造的自动化测试工具_哔哩哔哩_bilibiliSquish是一款跨平台、支持多种开发技术的GUI自动化测试工具&#xff0c;基于对象识别的GUI自动化测试工具、支持各类操作系统、可为多种技术开发的应用程序提供GUI自动化测试。操作简单、脚本语…

3乘3魔方第四步_三阶魔方第四步

三阶魔方的第四步是顶棱翻色&#xff0c;首先转出黄色的顶层十字&#xff0c;将魔方顺时针旋转九十度&#xff0c;转到红色的一面&#xff0c;右边顺时针旋转九十度&#xff0c;将底层的白色面转动到上面&#xff0c;顶层再顺时针旋转九十度&#xff0c;右侧逆时针旋转九十度&a…

java还原三阶魔方_魔方小站四阶魔方教程2 一看就懂的魔方教程(魔方玩法视频教程+还原公式一步一步图解+3D动画)...

形成下图的样子, 这一步很简单,只需要学会一个很好理解的技术就行了,请看下面标准情况的例子,魔方 您可以用鼠标拖拽3D动画里的整个魔方,以看到魔方背面的变化。 TR U R U 我们要合并位于前面的这一对红白棱块 合并棱块。 将合并好的一对红白棱块转到右面。 旋转右面,你要…