当前位置: 首页 > news >正文

Spring如何实现资源文件的加载

Spring如何实现资源文件的加载

Spring资源文件的加载依赖于Resource与ResourceLoader这两个类,采用采用的是策略模式与工厂方法相结合实现的

其中Resource是所有资源类型的父类,可以通过继承该类实现其getInputStream方法,获取资源文件的输入流,之后用过该输入流对象就可以实现对文件内容的读取。

除此之外为了更好的获取不同资源文件的Resource对象,这里采用了策略模式来根据不同的location获取获取Resource

手下我们需要创建一个Resource作为资源实现的接口,在该类当中定义了一个getInputStream方法,我们可以通过子类重写该方法,以实现不同类型资源的读取

public interface Resource {  
    /**  
     * 获取资源的输入流。  
     * @return 资源的输入流  
     */  
    InputStream getInputStream() throws IOException;  
  
}

ClassPathResource

public class ClassPathResource implements Resource{  
  
    // 文件相对路径  
    private final String path;  
    private final ClassLoader classLoader;  
  
    public ClassPathResource(String path) {  
        this.path = path;  
        this.classLoader = this.getClass().getClassLoader();  
    }  
  
  
    @Override  
    public InputStream getInputStream() throws FileNotFoundException {  
        InputStream inputStream = classLoader.getResourceAsStream(path);  
        if (inputStream == null){  
            throw new FileNotFoundException(String.format("%s,文件不存在",this.path));  
        }  
        return inputStream;  
  
    }  
}

FileSystemResource

public class FileSystemResource implements Resource{  
  
    private final String filePath;  
  
    public FileSystemResource(String filePath) {  
        this.filePath = filePath;  
    }  
  
    /**  
     * 获取资源的输入流。  
     *  
     * @return 资源的输入流  
     */  
    @Override  
    public InputStream getInputStream() throws FileNotFoundException {  
        try {  
            Path path = new File(this.filePath).toPath();  
            InputStream inputStream = Files.newInputStream(path);  
            return inputStream;  
        } catch (IOException e) {  
            throw new FileNotFoundException(String.format("%s,文件不存在",this.filePath));  
        }  
    }  
}

URLResource

public class URLResource implements Resource{  
    private final URL url;  
  
    public URLResource(URL url) {  
        this.url = url;  
    }  
  
    /**  
     * 获取资源的输入流。  
     *  
     * @return 资源的输入流  
     */  
    @Override  
    public InputStream getInputStream() throws IOException {  
        URLConnection urlConnection = this.url.openConnection();  
        InputStream inputStream = null;  
        inputStream = urlConnection.getInputStream();  
        return inputStream;  
  
    }  
}

![[Pasted image 20250409155558.png]]

通过以上三者就可以实现对ClassPath,系统文件,URL文件的解析

现在文件的解析方法定义好了,那何时解析调用哪种方式解析又成为了一个问题。在这里我们就通过策略模式来实现

在这里我们定义了一个ResourceLoader接口,并定义了getResource的一个抽象方法

public interface ResourceLoader {  
    /**  
     * 根据指定的位置获取资源  
     *  
     * @param location 资源的位置,通常是一个路径或URL  
     * @return 返回一个Resource对象,表示加载的资源  
     */  
    Resource getResource(String location);  
}

在此之后,再次定义一个默认的资源文件加载器实现ResourceLoader,在getResource方法当中会根据传入的location格式动态匹配对应的解析方法。

public class DefaultResourceLoader implements ResourceLoader{  
  
    // Classpath前缀  
    private final String CLASSPATH_URL_PREFIX = "classpath:";  
  
  
    /**  
     * 根据指定的位置获取资源  
     * 目前只实现了Classpath,URL,File  
     *     * @param location 资源的位置,通常是一个路径或URL  
     * @return 返回一个Resource对象,表示加载的资源  
     */  
    @Override  
    public Resource getResource(String location) {  
  
        // 加载ClassPath路径下的资源文件  
        if (location.startsWith(CLASSPATH_URL_PREFIX)){  
            return new ClassPathResource(location.substring(CLASSPATH_URL_PREFIX.length()));  
        }  
        // 加载路径资源文件  
        else if (location.startsWith("/")){  
            return new FileSystemResource(location.substring(1));  
        }  
        // 加载URl资源文件  
        else {  
            try {  
                URL url = new URL(location);  
                return new URLResource(url);  
            } catch (MalformedURLException e) {  
                return new FileSystemResource(location);  
            }  
        }  
  
    }  
}

现在我们就可以来测试一下

@Test  
public void testClassPathResource() throws IOException {  
    DefaultResourceLoader defaultResourceLoader = new DefaultResourceLoader();  
    Resource resource = defaultResourceLoader.getResource("classpath:hello.txt");  
    InputStream inputStream = resource.getInputStream();  
    String read = IoUtil.readUtf8(inputStream);  
    System.out.println(read);  
}
http://www.dtcms.com/a/122633.html

相关文章:

  • 网络安全之-信息收集
  • 国内协作机器手焊接领域领军人物分析
  • MCP 实战系列(Day 2)- 动手搓个文件系统 MCP 服务器
  • Linux系统管理与编程12: FTP服务配置
  • 《DataX 安装与简单使用指南》
  • 计算机视觉中的基于网格的卷绕算法全解析
  • Ansible(6)——管理变量
  • TDengine 数据模型设计:多列模式与单列模式对比(一)
  • UE5 matcap学习笔记
  • 单片机领域中哈希表
  • 基于 SpringBoot音乐网站与分享平台
  • 设计模式-命令模式详解
  • 大数据学习(104)-clickhouse与hdfs
  • Python web程序在服务器上面部署详细步骤
  • Java延迟队列
  • 铼赛智能Edge mini斩获2025法国设计大奖 | 重新定义数字化齿科美学
  • 深入解析 C++ 设计模式:原理、实现与应用
  • YOLOv12即插即用--CPAM
  • 【Kafka基础】消费者命令行完全指南:从基础到高级消费
  • 软考高级-系统架构设计师 案例题-软件架构设计
  • vue:前端预览 / chrome浏览器设置 / <iframe> 方法预览 doc、pdf / vue-pdf 预览pdf
  • 蓝桥杯 一年中的第几天(日期问题)
  • 如何运用浏览器进行各种调试?(网络、内存、控制台等调试用法)
  • 前端实战:基于Vue3与免费满血版DeepSeek实现无限滚动+懒加载+瀑布流模块及优化策略
  • Vert.x vs. Micronaut:2025年高并发Java框架选型指南
  • redisson常用加锁方式
  • 【代码模板】判断C语言中文件是否存在?错误:‘F_OK’未声明如何处理?(access;#include “unistd.h“)
  • 【智慧养猪场】-猪的行为分析视频数据集及展示(已做好分类)
  • C —— 宏
  • Redis-场景缓存+秒杀+管道+消息队列