【第18章】spring-resource


前言

在Spring框架中,Resource是一个关键组件,它位于org.springframework.core.io包中,用于处理资源的加载和访问。Resource接口为资源提供了一个抽象的表示,这些资源可以是文件、类路径上的资源、URL等。通过这个接口,Spring提供了一种统一的方式来加载和操作这些资源,无论它们实际上存储在哪里。

Resource接口的主要实现类包括:

ClassPathResource:表示类路径下的资源。它使用线程上下文类加载器、给定的类加载器或给定的类来加载资源。例如,你可以通过以下方式创建一个ClassPathResource对象:Resource resource = new ClassPathResource(“test.txt”);

UrlResource:表示一个URL资源。你可以通过URL字符串来创建它,例如:Resource resource = new UrlResource(“https://example.com/resource.txt”);

FileSystemResource:表示文件系统中的资源。Spring提供的这个类用于访问文件系统资源。

要使用Resource接口加载资源,首先需要获取一个ResourceLoader实例,这通常可以通过依赖注入来实现。一旦你有了ResourceLoader,你就可以使用它来加载各种资源。

Resource接口还定义了一系列方法,如exists(), isReadable(), getURL(), getFile()等,这些方法允许你查询资源的状态、获取资源的URL或文件等。

总的来说,Spring的Resource为开发者提供了一种灵活且强大的方式来处理应用程序中的资源。


一、Resource

1.测试类

package org.example.resource;

import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.Resource;
import org.springframework.core.io.UrlResource;
import org.springframework.util.ResourceUtils;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;

/**
 * Create by zjg on 2024/4/16
 */
public class ResourceTest {
    public static final String URL_PROTOCOL_HTTPS = "https";
    public static void main(String[] args) throws IOException {
        System.out.println("Hello Resource!");
        //ClassPathResource
        String path="jdbc.properties";
        loadClassPathResource(path);
        //FileSystemResource
        path="pom.xml";
        loadFileSystemResource(path);
        path="G:/workspace/spring6/pom.xml";
        loadFileSystemResource(path);
        //UrlResource
        path = "https://img-blog.csdnimg.cn/direct/dec4d833e4f64eb395567ac1e3746d0a.gif";
        loadUrlResource(path);
    }
    public static void loadClassPathResource(String path) throws IOException {
        ClassPathResource resource = new ClassPathResource(path);
        load(resource);
    }
    public static void loadFileSystemResource(String path) throws IOException {
        FileSystemResource resource = new FileSystemResource(path);
        load(resource);
    }
    public static void loadUrlResource(String path) throws IOException {
        UrlResource resource = new UrlResource(path);
        load(resource);
    }
    public static void load(Resource resource) throws IOException {
        System.out.println("--------------------------------------");
        boolean exists = resource.exists();
        System.out.println(exists);
        if(exists){
            System.out.println(resource.getURL());
            String protocol = resource.getURL().getProtocol();
            System.out.println(protocol);
            System.out.println(resource.getFilename());
            System.out.println(resource.contentLength()+"字节");
            System.out.println(resource.getDescription());
            if(resource instanceof ClassPathResource){//打印类路径
                System.out.println(ResourceUtils.getFile(ResourceUtils.CLASSPATH_URL_PREFIX).getPath());
            }
            if(ResourceUtils.URL_PROTOCOL_FILE.equals(protocol)){//打印绝对路径
                System.out.println(resource.getFile().getAbsolutePath());
            }
            if(URL_PROTOCOL_HTTPS.equals(protocol)){//下载到本地
                download(resource);
            }
        }
        System.out.println("--------------------------------------");
    }
    public static void download(Resource source) throws IOException {
        InputStream inputStream = source.getInputStream();
        //文件生成到项目根目录下
        FileOutputStream fileOutputStream = new FileOutputStream(source.getFilename());
        byte[] bytes=new byte[1024];//1kb
        int len;
        while ((len=inputStream.read(bytes))!=-1){
            fileOutputStream.write(bytes,0,len);
        }
    }
}

2.测试结果

Hello Resource!
--------------------------------------
true
file:/G:/workspace/spring6/spring-resource/target/classes/jdbc.properties
file
jdbc.properties
234字节
class path resource [jdbc.properties]
G:\workspace\spring6\spring-resource\target\classes
G:\workspace\spring6\spring-resource\target\classes\jdbc.properties
--------------------------------------
--------------------------------------
true
file:/G:/workspace/spring6/pom.xml
file
pom.xml
2601字节
file [G:\workspace\spring6\pom.xml]
G:\workspace\spring6\pom.xml
--------------------------------------
--------------------------------------
true
file:/G:/workspace/spring6/pom.xml
file
pom.xml
2601字节
file [G:\workspace\spring6\pom.xml]
G:\workspace\spring6\pom.xml
--------------------------------------
--------------------------------------
true
https://img-blog.csdnimg.cn/direct/dec4d833e4f64eb395567ac1e3746d0a.gif
https
dec4d833e4f64eb395567ac1e3746d0a.gif
18658字节
URL [https://img-blog.csdnimg.cn/direct/dec4d833e4f64eb395567ac1e3746d0a.gif]
--------------------------------------

二、ResourceLoader

ResourceLoader.getResource()得到资源对象,为向上造型,实际对象为其实现类。

1.测试类

package org.example.resource.loader;

import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.DefaultResourceLoader;
import org.springframework.core.io.Resource;
import org.springframework.util.ResourceUtils;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;

/**
 * Create by zjg on 2024/4/17
 */
public class ResourceLoaderTest {
    public static final String URL_PROTOCOL_HTTPS = "https";
    public static void main(String[] args) throws IOException {
        System.out.println("Hello ResourceLoader!");
        DefaultResourceLoader resourceLoader = new DefaultResourceLoader();
        //加载classpath文件
        Resource resource = resourceLoader.getResource("classpath:jdbc.properties");
        load(resource);
        //加载本地文件
        resource = resourceLoader.getResource("file:pom.xml");
        load(resource);
        resource = resourceLoader.getResource("file:G:\\workspace\\spring6\\pom.xml");
        load(resource);
        //加载网络文件
        resource = resourceLoader.getResource("https://img-blog.csdnimg.cn/direct/dec4d833e4f64eb395567ac1e3746d0a.gif");
        load(resource);
    }
    public static void load(Resource resource) throws IOException {
        System.out.println("--------------------------------------");
        boolean exists = resource.exists();
        System.out.println(exists);
        if(exists){
            System.out.println(resource.getURL());
            String protocol = resource.getURL().getProtocol();
            System.out.println(protocol);
            System.out.println(resource.getFilename());
            System.out.println(resource.contentLength()+"字节");
            System.out.println(resource.getDescription());
            if(resource instanceof ClassPathResource){//打印类路径
                System.out.println(ResourceUtils.getFile(ResourceUtils.CLASSPATH_URL_PREFIX).getPath());
            }
            if(ResourceUtils.URL_PROTOCOL_FILE.equals(protocol)){//打印绝对路径
                System.out.println(resource.getFile().getAbsolutePath());
            }
            if(URL_PROTOCOL_HTTPS.equals(protocol)){//下载到本地
                download(resource);
            }
        }
        System.out.println("--------------------------------------");
    }
    public static void download(Resource source) throws IOException {
        InputStream inputStream = source.getInputStream();
        //文件生成到项目根目录下
        FileOutputStream fileOutputStream = new FileOutputStream(source.getFilename());
        byte[] bytes=new byte[1024];//1kb
        int len;
        while ((len=inputStream.read(bytes))!=-1){
            fileOutputStream.write(bytes,0,len);
        }
    }
}

2.测试结果

Hello ResourceLoader!
--------------------------------------
true
file:/G:/workspace/spring6/spring-resource/target/classes/jdbc.properties
file
jdbc.properties
234字节
class path resource [jdbc.properties]
G:\workspace\spring6\spring-resource\target\classes
G:\workspace\spring6\spring-resource\target\classes\jdbc.properties
--------------------------------------
--------------------------------------
true
file:pom.xml
file
pom.xml
2601字节
URL [file:pom.xml]
G:\workspace\spring6\pom.xml
--------------------------------------
--------------------------------------
true
file:G:/workspace/spring6/pom.xml
file
pom.xml
2601字节
URL [file:G:/workspace/spring6/pom.xml]
G:\workspace\spring6\pom.xml
--------------------------------------
--------------------------------------
true
https://img-blog.csdnimg.cn/direct/dec4d833e4f64eb395567ac1e3746d0a.gif
https
dec4d833e4f64eb395567ac1e3746d0a.gif
18658字节
URL [https://img-blog.csdnimg.cn/direct/dec4d833e4f64eb395567ac1e3746d0a.gif]
--------------------------------------

三、ResourceLoaderAware

ResourceLoaderAware 接口是 Spring 框架中的一个特性,它允许 bean 在初始化时自动注入一个 ResourceLoader。ResourceLoader 是一个策略接口,用于加载类路径或文件系统上的资源。要使用 ResourceLoaderAware 接口,你需要实现该接口,并在实现中提供一个 setResourceLoader 方法,该方法将由 Spring 容器在 bean 初始化时自动调用。

上面的两种方式都是通过手动new的方式,耦合较强,未通过spring进行管理,下面我们来使用spring容器提供的回调接口来完成对资源的调用。

1.实现类

package org.example.resource.aware;

import org.springframework.context.ResourceLoaderAware;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
import org.springframework.util.ResourceUtils;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;

/**
 * Create by zjg on 2024/4/17
 */
public class DefaultResourceLoaderAware implements ResourceLoaderAware {
    public static final String URL_PROTOCOL_HTTPS = "https";
    private ResourceLoader resourceLoader;
    @Override
    public void setResourceLoader(ResourceLoader resourceLoader) {
        this.resourceLoader=resourceLoader;
        System.out.println("this.resourceLoader初始化完成"+this.resourceLoader);
    }

    public void getResource(String location) throws IOException {
        Resource resource = resourceLoader.getResource(location);
        System.out.println("--------------------------------------");
        boolean exists = resource.exists();
        System.out.println(exists);
        if(exists){
            System.out.println(resource.getURL());
            String protocol = resource.getURL().getProtocol();
            System.out.println(protocol);
            System.out.println(resource.getFilename());
            System.out.println(resource.contentLength()+"字节");
            System.out.println(resource.getDescription());
            if(resource instanceof ClassPathResource){//打印类路径
                System.out.println(ResourceUtils.getFile(ResourceUtils.CLASSPATH_URL_PREFIX).getPath());
            }
            if(ResourceUtils.URL_PROTOCOL_FILE.equals(protocol)){//打印绝对路径
                System.out.println(resource.getFile().getAbsolutePath());
            }
            if(URL_PROTOCOL_HTTPS.equals(protocol)){//下载到本地
                download(resource);
            }
        }
        System.out.println("--------------------------------------");
    }
    public static void download(Resource source) throws IOException {
        InputStream inputStream = source.getInputStream();
        //文件生成到项目根目录下
        FileOutputStream fileOutputStream = new FileOutputStream(source.getFilename());
        byte[] bytes=new byte[1024];//1kb
        int len;
        while ((len=inputStream.read(bytes))!=-1){
            fileOutputStream.write(bytes,0,len);
        }
    }
}

2.配置文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
        <bean id="defaultResourceLoaderAware" class="org.example.resource.aware.DefaultResourceLoaderAware"></bean>
</beans>

3.测试类

package org.example.resource.aware;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
import java.io.IOException;

/**
 * Create by zjg on 2024/4/17
 */
@SpringJUnitConfig(locations = "classpath:springContext.xml")
public class ResourceLoaderAwareTest {
    @Autowired
    DefaultResourceLoaderAware resourceLoaderAware;
    @org.junit.jupiter.api.Test
    public void test() throws IOException {
        //加载classpath文件
        resourceLoaderAware.getResource("classpath:jdbc.properties");
        //加载本地文件
        resourceLoaderAware.getResource("file:pom.xml");
        resourceLoaderAware.getResource("file:G:\\workspace\\spring6\\pom.xml");
        //加载网络文件
        resourceLoaderAware.getResource("https://img-blog.csdnimg.cn/direct/dec4d833e4f64eb395567ac1e3746d0a.gif");
    }
}

4.测试结果

this.resourceLoader初始化完成org.springframework.context.support.GenericApplicationContext@51549490, started on Wed Apr 17 22:25:17 CST 2024
--------------------------------------
true
file:/G:/workspace/spring6/spring-resource/target/classes/jdbc.properties
file
jdbc.properties
234字节
class path resource [jdbc.properties]
G:\workspace\spring6\spring-resource\target\classes
G:\workspace\spring6\spring-resource\target\classes\jdbc.properties
--------------------------------------
--------------------------------------
true
file:pom.xml
file
pom.xml
732字节
URL [file:pom.xml]
G:\workspace\spring6\spring-resource\pom.xml
--------------------------------------
--------------------------------------
true
file:G:/workspace/spring6/pom.xml
file
pom.xml
2601字节
URL [file:G:/workspace/spring6/pom.xml]
G:\workspace\spring6\pom.xml
--------------------------------------
--------------------------------------
true
https://img-blog.csdnimg.cn/direct/dec4d833e4f64eb395567ac1e3746d0a.gif
https
dec4d833e4f64eb395567ac1e3746d0a.gif
18658字节
URL [https://img-blog.csdnimg.cn/direct/dec4d833e4f64eb395567ac1e3746d0a.gif]
--------------------------------------

5.结论

在这里插入图片描述

可以看到,spring帮我们注入了一个上下文GenericApplicationContext,这个上下文的父类实现了ResourceLoader接口,在测试类中,我们所做的只有对DefaultResourceLoaderAware的方法调用,大大减少了调用时的代码量,也不用再去new各种对象了。


总结

回到顶部

  • 32
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值