spring源码解析-资源管理Resource

spring提供了常用的资源解析类,我们在平时读取文件过程中也可以直接采用,下面是我画的类图结构
资源类图
下面我进行一一介绍

/**
 * java通过class和classLoader获取资源的方式
 * @author q
 */
public class GetResourceTest {
    public static void main(String[] args) {
        //如果以'/'开头则从classpath路劲下获取
        System.out.println(GetResourceTest.class.getResource(""));
        System.out.println(GetResourceTest.class.getResource("/"));

        /**
         * classloader不能以'/'开头,否则为空,classloader是从classpath跟路劲开始获取
         */
        System.out.println(GetResourceTest.class.getClassLoader().getResource(""));
        System.out.println(GetResourceTest.class.getClassLoader().getResource("/"));
    }
}
/**
 * spring 资源获取策略
 * @author q
 *
 */
public class ResourceTest {
    public static void main(String[] args) throws IOException, URISyntaxException {
        /**
         * UriResource,通过网络协议读取文件资源
         */
        Resource res = new UrlResource("file:///D:/API/JAVA_API_1.7.chm");
        res.getFile();

        URI uri = new URI("file:///D:/API/JAVA_API_1.7.chm");
        System.out.println(uri.getSchemeSpecificPart());

        File file = new File("///D:/API/JAVA_API_1.7.chm");
        System.out.println(file.exists());

        /**
         * ClassPathResource最后通过this.classLoader.getResource(this.path)来获取资源,所以必须制定包路劲
         * @see GetResourceTest
         */
        res = new ClassPathResource("org/bear/bookstore/test/resource/application-orcl1.properties");
        System.out.println(res.getFile().exists());

        /**
         * InputStream不做解读
         */
        //res = new InputStreamResource(null);

        /**
         * To be used as placeholder if a {@code Resource} argument is
         * expected by an API but not necessarily used for actual reading
         */
        //res = new DescriptiveResource("file from native....");

        /**
         * ByteArrayResource不具体解读
         */
        //res = new ByteArrayResource(null);

        /**
         * FileSystemResource直接采用Java的File作为流
         */
        res = new FileSystemResource("D:/API/JAVA_API_1.7.chm");
        System.out.println("FileSystemResource:" + res.getFile().exists());

        /**
         * PathResource直接采用java中@see java.nio.Paths 获取流
         */
        res = new PathResource("D:/API/JAVA_API_1.7.chm");
        System.out.println("PathResource:" + res.getFile().exists());
    }
}

spring抽象出一个InputStreamResource接口,所有InputStream都可以作为资源供spring使用

public interface InputStreamSource {
    InputStream getInputStream() throws IOException;
}

抽象Resource作为资源判断、操作的接口,提供了一下操作

//是否存在
boolean exists();
//是否可读
boolean isReadable();
//是否已经打开
boolean isOpen();
//获取URL地址
URL getURL() throws IOException;
//获取资源定位符
URI getURI() throws IOException;
//获取文件
File getFile() throws IOException;
//获取资源大小
long contentLength() throws IOException;
//获取文件最后修改日期
long lastModified() throws IOException;
//
Resource createRelative(String relativePath) throws IOException;
//获取文件名
String getFilename();
//获取资源描述
String getDescription();

提供AbstractResource作为Resource接口的实现,注意其中几个方法,均需要其子类实现的,以为每一种方式都不相同,为设计模式策略模式的简单应用

public URL getURL() throws IOException {
    throw new FileNotFoundException(getDescription() + " cannot be resolved to URL");
}
public File getFile() throws IOException {
    throw new FileNotFoundException(getDescription() + " cannot be resolved to absolute file path");
}
public Resource createRelative(String relativePath) throws IOException {
    throw new FileNotFoundException("Cannot create a relative resource for " + getDescription());
}

剩下的子类就不多解释,资源管理并不复杂,spring提供多种方式获取资源:通过Url获取远程服务器资源,通过classLoader获取classpath下面的资源,通过File、Paths获取本地资源;我们也可以实现自己的资源获取策略供系统使用,有兴趣的可以自己尝试

补充

spring还提供了EncodedResource类,对Resource进行包装,提供通过不同编码方式读取资源文件,采用InputStreamReader读取Resource的流信息

public Reader getReader() throws IOException {
    if (this.charset != null) {
        return new InputStreamReader(this.resource.getInputStream(), this.charset);
    }
    else if (this.encoding != null) {
        return new InputStreamReader(this.resource.getInputStream(), this.encoding);
    }
    else {
        return new InputStreamReader(this.resource.getInputStream());
    }
}

近期准备深度研究spring源码,有工作中没有了解的关于spring的东西,大家可以提出来,我会有针对性研究和写文章,有什么写的不好的希望大家指正,谢谢

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值