我爱编程

Spring中的资源文件框架——Resource

2018-06-10  本文已影响0人  星流星

Spring中资源加载的框架

Spring对于资源加载有着一套自己的框架——Resource,Resource继承自InputStream。
下面的是Resource的源码:

public interface Resource extends InputStreamSource {

    boolean exists();
    default boolean isReadable() {
        return true;
    }
    default boolean isOpen() {
        return false;
    }
    default boolean isFile() {
        return false;
    }
    URL getURL() throws IOException;
    URI getURI() throws IOException;
    File getFile() throws IOException;
    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的继承图:(这里只是一部分)


Resource的继承图.png
package top.mcwebsite.resource;

import org.junit.Test;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.PathResource;
import org.springframework.core.io.Resource;
import org.springframework.core.io.WritableResource;

import java.io.*;

public class FileResourceTest {

    @Test
    public void testResource() throws IOException {
        String filePath = "E:\\源码\\Spring源码阅读\\testSpring\\src\\test\\resources\\spring.txt";

        // 1. 使用系统的文件路径方式加载文件
        WritableResource resource1 = new PathResource(filePath);

        // 2. 使用类路径方式加载文件
        Resource resource2 = new ClassPathResource("spring.txt");

        // 3. 使用WritableResource接口写资源文件
        OutputStream os = resource1.getOutputStream();
        os.write("Spring是一套非常优秀的框架".getBytes());

        // 4. 使用Resource接口读文件
        InputStream in1 = resource1.getInputStream();
        InputStream in2 = resource1.getInputStream();
        BufferedInputStream bis = new BufferedInputStream(in1);
        byte[] bytes = new byte[1024];
        bis.read(bytes);
        System.out.println(new String(bytes));
        System.out.println("resource1: " + resource1.getFilename());
        System.out.println("resource2: " + resource2.getFilename());
    }
}

随之而来的问题及解决

那就是Resource的选择,这么多的Resource如何知道选择使用哪一个?Spring提供了一个强大的资源加载机制,,他可以通过前缀标识加载资源,如:classpath, file等,同时还支持使用Ant风格的通配符。

  1. 资源地址的表示
地址前缀 示例 对应的资源类型
classpath: classpath:top/mcwebsite/resource/bean.xml 从类路径中加载资源,classpath:和classpath:/是等价的,都是相对于类的路径。资源文件可以在标准的文件系统中,也可以在JAR和ZIP的类包中
file: file:/config/bean,xml 使用UrlResource从文件系统目录中装载资源,可采用绝对或相对路径
http:// http://www.mcwebsite.top/bean.xml 使用UrlResource从Web服务器中装载资源
ftp:// ftp://www.mcwebsite.top/bean.xml 使用UrlResource从ftp服务器中装载资源
没有前缀 com/mcwebsite/resource/bean.xml 根据ApplicationContext的具体实现曹勇对应类型的Resource

关于classpath:和classpath:前缀。如果有多个JAR包或文件系统路径都拥有同一个相同的包。classpath:只会找到第一个加载的,而classpath:会扫描所有的这些JAR包及类路径下出现的。

Ant风格的资源地址支持三种通配符:

ResourceLoader接口仅有一个getResource(String location)方法,可根据资源地址加载资源。不过,资源地址仅支持带资源类型前缀的表达式,不支持Ant风格的资源路径表达式。ResourcePatternResolver扩展ResourceLoader接口,定义了一个新的接口方法getResources(String locationPatern),该方法支持带资源前缀及Ant风格的资源路径表达式。


import java.io.IOException;
import static org.junit.Assert.assertNotNull;
public class PatternResolverTest {
    @Test
    public void getResources() throws IOException {
        ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
        Resource[] resources = resolver.getResources("classpath:*.xml");
        assertNotNull(resources);
        for (Resource resource : resources) {
            System.out.println(resource.getDescription());
        }
    }
}

上一篇 下一篇

猜你喜欢

热点阅读