Spring Core——资源加载与访问(Resource)

Spring 中的资源加载

在Spring框架中,Resource接口用于简化和统一对各种底层资源(如xxx.xml、application.yml、application.properties等文件、类路径资源、URL等)的访问。它提供了一个通用的抽象层,使开发者无需关注不同资源类型的具体访问方式。在Java开发中,访问资源是一个常见需求,例如读取配置文件、加载图片、音频等。Java标准库为不同类型的资源提供了各自的访问方式。例如,文件系统资源通常使用java.io.File类,类路径资源可能使用ClassLoadergetResourcegetResourceAsStream方法,而网络资源则可以通过java.net.URL类进行访问。这些不同的机制意味着开发者需要熟悉多种方式来访问资源,这可能导致代码复杂性增加、重复代码出现以及更高的错误风险。

为了解决这些问题并提供一个更统一的资源访问方式,Spring框架引入了Resource接口。Resource接口为所有资源类型提供了一个通用的抽象,使得无论资源来自文件系统、类路径还是网络,开发者都可以通过一致的方式进行访问。这不仅简化了资源访问的代码,还提高了代码的可维护性和可读性。此外,Spring还提供了多个Resource接口的实现类,例如FileSystemResource、ClassPathResource、UrlResource等,这些类专门用于处理特定类型的资源。通过使用这些实现类,开发者可以轻松地从不同来源获取资源,而不必担心底层的实现细节。总之,Resource接口及其实现类为资源访问提供了一种高度抽象和简化的解决方案,是Spring框架中一个非常有用的功能。

本文将从Resource接口开始介绍,最后将介绍常用的Resources接口的实现类ResourceLoaderResourcePatternResolverDocumentLoader等。

Resource接口

Spring中将所有的资源抽象成了Resource对象,对于不同的资源类型有着不同的实现类,它为访问底层资源提供了一个统一的抽象,从而使得代码可以独立于实际资源的类型。首先我们打开Resource源代码如下所示:

/**
 * 用于描述资源的接口,该接口抽象了底层资源的实际类型,如文件或类路径资源。
 *
 * <p>对于每个资源,如果它在物理形式上存在,都可以打开一个输入流,但只有某些资源才能返回 URL 或文件句柄。具体行为取决于其实现。
 */
public interface Resource extends InputStreamSource {

    /**
     * 判断此资源是否在物理形式上真正存在。
     */
    boolean exists();

    /**
     * 指示是否可以通过 {@link #getInputStream()} 读取此资源的非空内容。
     * 实际的内容读取可能仍然失败。
     */
    default boolean isReadable() {
        return exists();
    }

    /**
     * 指示此资源是否代表一个打开的流的句柄。
     * 如果为 true,则输入流不能被多次读取,并且在读取后必须被关闭,以避免资源泄露。
     */
    default boolean isOpen() {
        return false;
    }

    /**
     * 判断此资源是否代表文件系统中的文件。
     */
    default boolean isFile() {
        return false;
    }

    /**
     * 返回此资源的 URL 句柄。
     */
    URL getURL() throws IOException;

    /**
     * 返回此资源的 URI 句柄。
     */
    URI getURI() throws IOException;

    /**
     * 返回此资源的文件句柄。
     */
    File getFile() throws IOException;

    /**
     * 返回一个 {@link ReadableByteChannel}。
     */
    default ReadableByteChannel readableChannel() throws IOException {
        return Channels.newChannel(getInputStream());
    }

    /**
     * 确定此资源的内容长度。
     */
    long contentLength() throws IOException;

    /**
     * 确定此资源的最后修改时间戳。
     */
    long lastModified() throws IOException;

    /**
     * 创建相对于此资源的资源。
     */
    Resource createRelative(String relativePath) throws IOException;

    /**
     * 返回此资源的文件名。
     */
    @Nullable
    String getFilename();

    /**
     * 返回此资源的描述,用于在处理资源时的错误输出。
     */
    String getDescription();
}

可以看见Resource接口是InputStreamSource的子类,我们可以看一下InputStreamSource的源码如下:

/**
 * 表示可以提供输入流的资源或对象的接口。
 */
public interface InputStreamSource {
	/**
	 * 返回基础资源内容的 InputStream。
	 * 期望每次调用都会创建一个新的流。
	 * @return 基础资源的输入流(不能为 null)
	 * @throws java.io.FileNotFoundException 如果基础资源不存在
	 * @throws IOException 如果无法打开内容流
	 */
	InputStream getInputStream() throws IOException;
}

ResourceLoader类

ResourcePatternResolver类

DocumentLoader类

  • 5
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

矩阵科学

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值