Spring的资源Resource和ResourceLoader
两者区别和联系
Resource
和ResourceLoader
都是 Spring 框架中用于资源访问的接口
Resource 是“资源本身”,ResourceLoader 是“资源工厂/加载器”,负责创建 Resource。 Resource:Spring 统一抽象的“资源”对象,可以表示文件、类路径下的文件、URL、字节流等各种资源(统一封装各种类型的资源访问,屏蔽底层细节) 常见实现类: ClassPathResource(类路径下的资源) FileSystemResource(文件系统资源) UrlResource(URL 资源) ServletContextResource(Web 应用资源) ResourceLoader: Spring 的资源加载器接口,负责根据资源路径加载并返回 Resource 对象(负责“解析”资源路径(如 classpath:、file:、http: 等),并返回对应的 Resource 实例。) 常用实现类: DefaultResourceLoader(Spring 默认实现) ApplicationContext(它本身就是 ResourceLoader 的实现)
Resource
Resouce家族族谱
ClassPathResource
ClassPathResource
类:该资源类型在Spring中是非常常用的一种资源类型,用来访问类加载路径下的资源,相对于其他的Resource类型,该种类型在Web应用中可以自动搜索位于WEB-INF/classes下的资源文件,而无需使用绝对路径访问。
1、访问类路径下资源
@Test// 读取类路径下的资源 ClassPathResource(String path)
public void classPathResource() throws IOException {Resource classPathResource = new ClassPathResource("application.properties");InputStream inputStream = classPathResource.getInputStream();// 使用 apache下的 IOUtils 将流 转成 stringString content = IOUtils.toString(inputStream, StandardCharsets.UTF_8);System.out.println(content);
}
2、模块1项目内访问模块2项目下的资源
user-upload 模块下有两个项目
user-upload-api
user-upload-service
//user-upload-service 下访问 user-upload-api 下类路径资源
// ClassPathResource(String path, @Nullable ClassLoader classLoader)@Testvoid test() throws IOException {Resource resource2 = new ClassPathResource("application-api.properties", Constants.class.getClassLoader());System.out.println(IOUtils.toString(resource2.getInputStream(), StandardCharsets.UTF_8));}
FileSystemResource
FileSystemResource 是 Spring 框架中用于访问文件系统中资源的一个实现类
-
你可以用它来访问任意路径下的文件(绝对路径或相对路径(相对于当前工作目录(working directory)的相对路径))。
@Testvoid fileSystemResource() throws IOException {
// 查看当前工作目录System.out.println(System.getProperty("user.dir"));// 如果是相对路径 就是 工作目录+相对路径Resource resource = new FileSystemResource("src/test/java/com/yuan/springboot/spring/resource/test.txt");System.out.println(IOUtils.toString(resource.getInputStream(), StandardCharsets.UTF_8));
// 2、绝对路径Resource resource2 = new FileSystemResource("/Users/liuyuanyuan/JavaProject/study/springboot/src/test/java/com/yuan/springboot/spring/resource/test.txt");System.out.println(IOUtils.toString(resource2.getInputStream(), StandardCharsets.UTF_8));}
UrlResource
// 3. UrlResource - 访问URL资源
Resource urlResource = new UrlResource("https://example.com/file.txt");
URL url = urlResource.getURL();
ServletContextResource
ServletContextResource
类:是ServletContext
资源的Resource
实现,用来访问相对于ServletContext路径下的资源。支持以流和URL的方式进行访问,但只有在扩展Web应用程序存档且资源实际位于文件系统上时才允许java.io.File访问。
-
实际应用场景:
@Service
public class WebResourceService {private final ServletContext servletContext;public WebResourceService(ServletContext servletContext) {this.servletContext = servletContext;}public void processWebResource() {// 访问 WEB-INF 目录下的配置文件Resource configResource = new ServletContextResource(servletContext, "/WEB-INF/config.properties");// 访问静态资源Resource staticResource = new ServletContextResource(servletContext, "/static/images/logo.png");// 访问上传的文件Resource uploadResource = new ServletContextResource(servletContext, "/uploads/user-file.txt");try {if (configResource.exists()) {Properties props = new Properties();props.load(configResource.getInputStream());// 处理配置...}if (staticResource.exists()) {// 处理静态资源...}if (uploadResource.exists()) {// 处理上传的文件...}} catch (IOException e) {// 处理异常...}}
}
@Controller
public class FileController {private final ServletContext servletContext;public FileController(ServletContext servletContext) {this.servletContext = servletContext;}@GetMapping("/download")public void downloadFile(HttpServletResponse response) throws IOException {// 获取要下载的文件资源Resource fileResource = new ServletContextResource(servletContext, "/uploads/document.pdf");if (fileResource.exists()) {// 设置响应头response.setContentType("application/pdf");response.setHeader("Content-Disposition", "attachment; filename=document.pdf");// 将文件内容写入响应try (InputStream is = fileResource.getInputStream();OutputStream os = response.getOutputStream()) {IOUtils.copy(is, os);}}}@PostMapping("/upload")public String handleFileUpload(@RequestParam("file") MultipartFile file) throws IOException {// 获取上传目录的路径String uploadDir = servletContext.getRealPath("/uploads");// 创建上传目录File dir = new File(uploadDir);if (!dir.exists()) {dir.mkdirs();}// 保存文件File destFile = new File(dir, file.getOriginalFilename());file.transferTo(destFile);return "redirect:/success";}
}
ResourceLoader
ResourceLoader 是资源加载器接口,用于加载资源。Spring 提供了默认实现 DefaultResourceLoader。
DefaultResourceLoader
ResourceLoader 提供多种资源方式的访问 提供getResource 方法
@Testvoid ResourceLoader() throws IOException {
// 1、调用的是 ClassPathResource 加载类路径资源ResourceLoader resourceLoader = new DefaultResourceLoader();Resource resource1 = resourceLoader.getResource("classpath:static/index.html");System.out.println(IOUtils.toString(resource1.getInputStream(), StandardCharsets.UTF_8));
//2、调用的是 ClassPathContextResource 实际还是 ClassPathResource 他会帮我们去掉/ 加载类路径资源Resource resource2 = resourceLoader.getResource("/static/index.html");System.out.println(IOUtils.toString(resource2.getInputStream(), StandardCharsets.UTF_8));
// 3、调用的是 UrlResource 加载URL资源 支持file访问本地资源(相对和绝对都支持) 支持访问网络资源Resource resource3_1 = resourceLoader.getResource("http://www.baidu.com");System.out.println(IOUtils.toString(resource3_1.getInputStream(), StandardCharsets.UTF_8));Resource resource3_2 = resourceLoader.getResource("file:src/test/java/com/yuan/springboot/spring/resource/test.txt");System.out.println(IOUtils.toString(resource3_2.getInputStream(), StandardCharsets.UTF_8));Resource resource3_3 = resourceLoader.getResource("file:/Users/liuyuanyuan/JavaProject/study/springboot/src/test/java/com/yuan/springboot/spring/resource/test.txt");System.out.println(IOUtils.toString(resource3_3.getInputStream(), StandardCharsets.UTF_8));
// 4、调用的是 FileUrlResource 支持 绝对/相对 访问本地资源 其中相对是指项目的工作目录下Resource resource4_1 = resourceLoader.getResource("file:src/test/java/com/yuan/springboot/spring/resource/test.txt");Resource resource4_2 = resourceLoader.getResource("file:/Users/liuyuanyuan/JavaProject/study/springboot/src/test/java/com/yuan/springboot/spring/resource/test.txt");System.out.println(IOUtils.toString(resource4_1.getInputStream(), StandardCharsets.UTF_8));System.out.println(IOUtils.toString(resource4_2.getInputStream(), StandardCharsets.UTF_8));
}
FileSystemResource、FileUrlResource、UrlResource 总结
类名 | 支持本地文件 | 支持网络资源 | 路径格式 | 典型场景 |
---|---|---|---|---|
FileSystemResource | 是 | 否 | 绝对/相对文件路径 | 只操作本地文件 |
FileUrlResource | 是 | 否 | file: 协议的 URL | 需要用 URL 方式访问本地文件 |
UrlResource | 是 | 是 | 任意 URL(http/file等) | 统一处理网络和本地资源 |
DefaultResourceLoader 是 ResourceLoader 的默认实现
核心方法是getResource
1、里面有个ProtocolResolver,允许用户自定义协议资源解决策略,作为 DefaultResourceLoader 的 SPI,它允许用户自定义资源加载协议,而不需要继承 ResourceLoader 的子类。 在这个接口类中只有一个方法。
所以有了 ProtocolResolver 后,我们不需要直接继承 DefaultResourceLoader,改为实现 ProtocolResolver 接口也可以实现自定义的 ResourceLoader
2、执行逻辑
若 location 以/开头,则调用 getResourceByPath()构造 ClassPathContextResource 类型资源并返回; 若 location 以 classpath:开头, 则构造 ClassPathResource 类型资源并返回,在构造该资源时,通过 getClassLoader()获取当前的 ClassLoader; 构造 URL,尝试通过它进行资源定位,若没有抛出 MalformedURLException 异常,然后判断是否为 FileURL,如果是则构造 FileUrlResource 类型资源,否则构造 UrlResource。若在加载过程中抛出 MalformedURLException 异常,则 委派 getResourceByPath() 实现资源定位加载。
FileSystemResourceLoader
-
FileSystemResourceLoader:适合你只想从本地文件系统加载资源,不需要支持 classpath 或网络资源的场景。
-
DefaultResourceLoader:适合需要支持多种资源类型(classpath、file、url等)的通用场景。
@Testvoid test() throws IOException {//实际上,FileSystemResourceLoader 的功能比 DefaultResourceLoader 更窄,它只能加载文件系统资源,不支持 classpath、http、ftp 等其他协议。// 而且你调用 getResource 还是在调用 FileSystemResourceLoader 父类DefaultResourceLoader的 getResource 方法 因为 FileSystemResourceLoader 根本没重写这个方法FileSystemResourceLoader fileSystemResourceLoader = new FileSystemResourceLoader();
// 这个最终会调用 FileUrlResourceResource resource1 = fileSystemResourceLoader.getResource("src/test/java/com/yuan/springboot/spring/resource/test.txt");System.out.println(IOUtils.toString(resource1.getInputStream(), StandardCharsets.UTF_8));
// 这个会报错 因为他最后给你构造成 ClassPathContextResource 这个是从类路径下找资源的Resource resource2 = fileSystemResourceLoader.getResource("/Users/liuyuanyuan/JavaProject/study/springboot/src/test/java/com/yuan/springboot/spring/resource/test.txt");System.out.println(IOUtils.toString(resource2.getInputStream(), StandardCharsets.UTF_8));
}
ResourcePatternResolver
ResourcePatternResolver接口继承了ResourceLoader, 是ResourceLoader的扩展
是 Spring 框架中用于批量加载资源的接口,支持通配符(如 *、**)和多种资源协议(classpath、file、http等)
PathMatchingResourcePatternResolver:Spring 默认实现,最常用
case
@Testvoid resourcePatternResolver() throws IOException {ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
// 查找 classpath static 下所有 txt 文件//classpath*: 表示所有 classpath 路径(包括依赖 jar 包里的资源)。//** 表示递归查找所有子目录。Resource[] resources = resolver.getResources("classpath*:static/**/*.txt");for (Resource resource : resources) {System.out.println(resource.getFilename());}}
相关文章:

Spring的资源Resource和ResourceLoader
两者区别和联系 Resource 和ResourceLoader 都是 Spring 框架中用于资源访问的接口 Resource 是“资源本身”,ResourceLoader 是“资源工厂/加载器”,负责创建 Resource。 Resource:Spring 统一抽象的“资源”对象,可以表示文件、类路径下的文件、U…...
字节跳动旗下火山引擎都覆盖哪些领域
首先,我需要确认火山引擎的主要业务范围。根据之前的资料,火山引擎是字节跳动的企业技术服务平台,可能包括云服务、人工智能、大数据分析等。不过需要更详细的信息,比如具体的产品和服务,覆盖的行业等。 接下来&#x…...

【AI实战】从“苦AI”到“爽AI”:Magentic-UI 把“人类-多智能体协作”玩明白了!
Hello,亲爱的小伙伴们!你是否曾经在深夜里,为了自动化点外卖、筛机票、抓网页数据焦头烂额?有没有幻想过哪天能出个“贴心AI管家”,一键点菜、搞定事务、自动操作网页,比你还懂你?更关键——还让…...
LeetCode面试经典150题梳理
link:https://leetcode.cn/studyplan/top-interview-150/ 日期题号备注2025.5.2288. 合并两个有序数组 - 力扣(LeetCode)通过双指针法从后向前合并来解决,避免覆盖nums1中的元素2025.5.2327. 移除元素 - 力扣(LeetCode…...
ABP VNext + Orleans:Actor 模型下的分布式状态管理最佳实践
ABP VNext Orleans:Actor 模型下的分布式状态管理最佳实践 🚀 📚 目录 ABP VNext Orleans:Actor 模型下的分布式状态管理最佳实践 🚀一、引言:分布式系统的状态挑战 💡二、架构图与技术栈 &am…...

Linux之 SPI 驱动框架- spi-mem 框架
一、框架变更的历程 1.1 旧框架图 1.2 新框架图 那么问题来了, 为什么要开发新的 SPI 存储器接口? 有了这个新的框架, SPI NOR 和SPI NAND 都可以基于相同的SPI控制器驱动进行支持了。m25p80 驱动将被修改成,使用spi-mem 接口&a…...

振动分析 - 献个宝
1.一个自制的振动能量分析工具 这个分析工具似乎真的定位到了故障的具体位置。 1.1对一组实验室虚拟信号的分析结果: 1.2 对现场真实数据的分析结果 依照边频带的调制,和边频的缝隙宽度,基本定位到问题。 追加几份待看的文档: 齿轮结构的频谱特征 - 知乎使用 FFT 获得…...
从脑电图和大脑记录中学习稳健的深度视觉表征
从脑电图和大脑记录中学习稳健的深度视觉表征 印度,印度,印度,印度大脑实验室,印度 例如,达拉普,克普拉萨德,山,山,新的。ac .在 摘要 解码人类大脑一直是新机器人科学家…...

【论文阅读】——D^3-Human: Dynamic Disentangled Digital Human from Monocular Vi
文章目录 摘要1 引言2 相关工作3 方法3.1 HmSDF 表示3.2 区域聚合3.3. 变形场3.4. 遮挡感知可微分渲染3.5 训练3.5.1 训练策略3.5.2 重建损失3.5.3 正则化限制 4. 实验4.1 定量评估4.2 定性评价4.3 消融研究4.4 应用程序 5 结论 摘要 我们介绍 D 3 D^{3} D3人,一种…...

高分辨率北半球多年冻土数据集(2000-2016)
关键数据集分类:冰冻圈数据集时间分辨率:10 year < x < 100 year空间分辨率:1km - 10km共享方式:开放获取数据大小:339.79 MB数据时间范围:2000-01-01 — 2016-12-31元数据更新时间:2022-…...
Prompt Tuning:轻量级大模型微调全攻略
Prompt Tuning(提示调优)步骤金额流程 传统的 Prompt Tuning(提示调优) 是一种轻量级的大模型微调技术,核心是通过优化连续的提示向量(而非模型参数)来适配特定任务。 一、核心步骤概述 准备任务与数据 明确任务类型(如分类、问答等),准备输入文本和目标标签。加载…...
【VBA 字典的引用和调用方法】
如何引用字典对象。在VBA中,字典不是内置的,所以需要引用Microsoft Scripting Runtime库。 在 VBA 中使用 Dictionary(字典)对象可以方便地存储键值对(Key-Item)数据,以下是引用方法和常用参数介…...

基于开源AI智能名片链动2+1模式S2B2C商城小程序的管理与运营策略研究
摘要:本文通过分析开源AI智能名片链动21模式S2B2C商城小程序的技术架构与商业逻辑,探讨其在企业管理与运营中的实践价值。结合案例研究,论证该模式如何通过清晰的目标设定、动态反馈机制和资源整合能力,提升团队执行力与客户粘性。…...

储能电站:风光储一体化能源中心数字孪生
在 “双碳” 目标引领下,我国能源产业加速向清洁低碳、绿色化转型,风能、太阳能等可再生能源的开发利用成为关键。然而,风能和太阳能的波动性、间歇性与随机性,给大规模接入电网带来挑战。储能技术的兴起,为解决这一难…...
iOS 直播特殊礼物特效实现方案(Swift实现,超详细!)
特殊礼物特效是提升直播互动体验的关键功能,下面我将详细介绍如何在iOS应用中实现各种高级礼物特效。 基础特效类型 1.1 全屏动画特效 class FullScreenAnimationView: UIView {static func show(with gift: GiftModel, in view: UIView) {let effectView FullS…...

9. 现代循环神经网络
文章目录 9.1. 门控循环单元(GRU)9.1.1. 门控隐状态9.1.1.1. 重置门和更新门9.1.1.2. 候选隐状态9.1.1.3. 隐状态 9.1.2. 从零开始实现9.1.2.1. 初始化模型参数9.1.2.2. 定义模型 9.1.3. 简洁实现9.1.4. 小结 9.2. 长短期记忆网络(LSTM&#…...

视频太大?用魔影工厂压缩并转MP4,画质不打折!
在日常生活中,我们常常需要将视频文件转换成不同的格式以适应各种设备或平台的播放需求。魔影工厂作为一款功能强大且操作简单的视频转换工具,深受用户喜爱。本文中简鹿办公将手把手教你如何使用魔影工厂将视频转换为MP4格式,并进行个性化设置…...
Python中tqdm进度条工具和enumerate函数的使用详解
tqdm进度条工具 tqdm 是 Python 中一个非常流行的 进度条显示工具库,常用于迭代操作的可视化,比如训练神经网络、批量数据处理等任务。 一、tqdm 是什么? tqdm 全称是 taqaddum(阿拉伯语,意为“进展”)&a…...

最宽温度范围文本格式PT1000分度表-200~850度及PT1000铂电阻温度传感器计算公式
常用PT铂电阻温度传感器 该图片来自网络,在此对图片作者表示感谢。 白色陶瓷面为测温面。 近距离图片。 常用的有PT100、PT500、PT1000,不常用的还有 PT50、PT200、PT10000等,PT代表铂电阻,后面的数字是零摄氏度时电阻值&#…...
基于Netty架构的充电桩系统设计:服务器运维如何更好保障稳定性?
Netty是一个异步事件驱动的网络应用框架,用于快速开发高性能、高可靠性的网络服务器和客户端。它本质上是NIO的封装和增强,主要针对TCP/IP协议下高性能网络通信场景。 本设计通过Netty的高性能网络通信能力,结合充电桩行业特性,实…...
操作系统学习笔记第1章 操作系统概述(灰灰题库
1.单选题 用户发起系统服务请求时,处理器处于______。 A. 用户态 B. 核心态 C. 阻塞态 D. 挂起态 第 1 题 答案:A 解析:用户态下,用户程序只能执行非特权指令 。当用户发起系统服务请求(通常通过系统调用)时…...
后端开发实习生-抖音生活服务
职位描述 ByteIntern:面向2026届毕业生(2025年9月-2026年8月期间毕业),为符合岗位要求的同学提供转正机会。 团队介绍:生活服务业务依托于抖音、抖音极速版等平台,致力于促进用户与本地服务的连接。过去一…...

机器学习算法-sklearn源起
scikit-learn(简称 sklearn)是 Python 中最流行的开源机器学习库之一,基于 NumPy、SciPy 和 Matplotlib 构建。它提供了丰富的机器学习算法和工具,适用于数据挖掘和数据分析任务。以下是其核心特点的简介: 1、sklearn主…...
Keepalived 在不同场景下的高可用方案设计与最佳实践
一、Keepalived 典型应用场景深度解析 1. Web 服务器集群:统一入口与故障容错 1.1 场景需求 核心目标:为多台 Web 服务器提供统一 VIP 入口,隐藏后端节点细节,实现故障透明切换。 挑战: 确保用户请求在主节点故障时…...

注册并创建一个微信小程序
目录 (一)前往微信公众平台,并注册一个微信小程序账号 (二)配置微信小程序 (三)创建微信小程序项目 1.流程 1.1获取小程序ID 1.2下载微信开发者工具 1.3安装微信开发者工具 2.创建项目…...
CentOS 10:启动telnet服务
参考, 鳥哥私房菜 - 第七章、網路安全與主機基本防護:限制埠口, 網路升級與 SELinux 7.3.3 埠口与服务的启动/关闭及开机时状态设定 我们知道系统的 Telnet 服务通常是以 super daemon 来控管的,请您启动您系统的 telnet 试看看。 1 要启动 …...

计算机网络——每一层的用到的设备及其作用
计算机网络基础 OSI参考模型TCP/IP协议族集线器(Hub)交换机(Switch)路由器(Router)功能特点无线路由器(家庭宽带)光猫功能 网关(Gateway)功能应用场景特点 IP…...
OpenLayers 加载鹰眼控件
注:当前使用的是 ol 5.3.0 版本,天地图使用的key请到天地图官网申请,并替换为自己的key 地图控件是一些用来与地图进行简单交互的工具,地图库预先封装好,可以供开发者直接使用。OpenLayers具有大部分常用的控件&#x…...
Eigen与OpenCV矩阵操作全面对比:最大值、最小值、平均值
功能对比总表 功能Eigen 方法OpenCV 方法主要区别最大值mat.maxCoeff(&row, &col)cv::minMaxLoc(mat, NULL, &maxVal, NULL, &maxLoc)Eigen需要分开调用,OpenCV一次获取最小值mat.minCoeff(&row, &col)cv::minMaxLoc(mat, &minVal, NU…...
安全基础与协议分析
5.1 Web安全基础 5.1.1 Web安全基础概览(一、二) Web安全的核心目标是保护Web应用及其数据免受攻击,涵盖以下关键领域: 攻击面: 前端漏洞(XSS、CSRF)。 后端漏洞(SQL注入、RCE&a…...