前些日子看《深入理解javaweb开发》时,看到第一章java的io流,发觉自己对io流真的不是很熟悉。然后看了下JDK1.7中io包的一点点代码,又看了org.springframework.core.io包的一些类和组织方式,当作是学习吧。总结一下。

先挂下spring.core.io包的类图,其中接口是方框表示,抽象类带了abstract前缀,剩下那个两个框重贴的则代表实现类。没怎么划过类图,如果有好的画类图工具请推荐给我。

画得不好的地方就见谅了。注:以下源码匹配的是spring-core-4.1.6Release.jar里面的org.springframework.core.io包。

先看处于最上层的接口,叫InputStreamSource,里面只有一个抽象方法

接下是resources,这个接口我们一般都会用到,贴源码:

public interface Resource extends InputStreamSource {

    boolean exists();//文件是否存在

    boolean isReadable();//是否可读

    boolean isOpen();//资源是否被一个inputstream打开,如果已被打开,则不允许其他流再打开

    URL getURL() throws IOException;//获取资源url路径,当不能以url描述时抛出ioException异常

    URI getURI() throws IOException;//获取资源uri路径,当不能以url描述时抛出ioException异常

    File getFile() throws IOException;//获取file,file在IO流中仅仅是一个指向作用

    long contentLength() throws IOException;//资源的字节长度,可以拿来算资源的大小

    long lastModified() throws IOException;//资源最后修改时间

    Resource createRelative(String relativePath) throws IOException;//根据资源相对路径创建资源

    String getFilename();//返回文件名

    String getDescription();//资源描述

}

后面是abstractResource,这是个挺重要的类,主要是对resource接口的基本实现,

public abstract class AbstractResource implements Resource {

    @Override
public boolean exists() {
//看是否能在硬盘上找到
try {
return getFile().exists();
}
catch (IOException ex) {
// 试一下能不能打开输出流
try {
InputStream is = getInputStream();
is.close();
return true;
}
catch (Throwable isEx) {
return false;
}
}
} /**
* 一般都是可读的,所以默认方法是true
*/
@Override
public boolean isReadable() {
return true;
} /**
* 默认值是false,没有inputStream来读时的默认状态
*/
@Override
public boolean isOpen() {
return false;
} /**
* url这个属性一般只出现在web的IO资源中,网络resource需要override这个方法,其他类型资源敢访问这个方法,抛个异常给他
*/
@Override
public URL getURL() throws IOException {
throw new FileNotFoundException(getDescription() + " cannot be resolved to URL");
} @Override
public URI getURI() throws IOException {
URL url = getURL();
try {
//url可以转成uri,uri不能转url
return ResourceUtils.toURI(url);
}
catch (URISyntaxException ex) {
throw new NestedIOException("Invalid URI [" + url + "]", ex);
}
} /**
* JDK的File类都是返回绝对路径的File,当一个资源没有绝对路径时,抛个异常给它没毛病
*/
@Override
public File getFile() throws IOException {
throw new FileNotFoundException(getDescription() + " cannot be resolved to absolute file path");
} /**
* inputStream读取byte[]字节流,并返回该数组的长度,相当于把文件读了一次
*/
@Override
public long contentLength() throws IOException {
InputStream is = this.getInputStream();
//Assert应该是叫断言
Assert.state(is != null, "resource input stream must not be null");
try {
long size = 0;
byte[] buf = new byte[255];
int read;
while ((read = is.read(buf)) != -1) {
size += read;
}
return size;
}
finally {
try {
//一定要在finally中关闭流
is.close();
}
catch (IOException ex) {
}
}
} /**
* 返回getFileForLastModifiedCheck().lastModified()的值,该职为0L,抛个异常给他没毛病
*/
@Override
public long lastModified() throws IOException {
long lastModified = getFileForLastModifiedCheck().lastModified();
if (lastModified == 0L) {
throw new FileNotFoundException(getDescription() +
" cannot be resolved in the file system for resolving its last-modified timestamp");
}
return lastModified;
} /**
* 调用getFile方法
*/
protected File getFileForLastModifiedCheck() throws IOException {
return getFile();
} /**
* 直接假定相对资源创建不了,再抛个异常给他
*/
@Override
public Resource createRelative(String relativePath) throws IOException {
throw new FileNotFoundException("Cannot create a relative resource for " + getDescription());
} /**
* 又是一个假定,假定filename文件名为null
*/
@Override
public String getFilename() {
return null;
} /**
* 很简单,不解释
*/
@Override
public String toString() {
return getDescription();
} /**
* 判断两文件是否相等
*/
@Override
public boolean equals(Object obj) {
return (obj == this ||
(obj instanceof Resource && ((Resource) obj).getDescription().equals(getDescription())));
} /**
* 返回hashCode
*/
@Override
public int hashCode() {
return getDescription().hashCode();
} }

至于其他实现类其实都是在接口和抽象类的基础上去拓展,所以我并不是读得很仔细,先这样子吧。

小总结:其实为什么要分好几层去继承刚开始我是很不懂的,后面看了源代码和小伙伴的博文后便豁然开朗了。

1.resources是高度抽象的接口,里面是对所有资源文件的具体方法抽象,但是并不是每个资源都有这个抽象里面的所有方法,所以abstractResource对其进行了一般的实现,

对于一些并不是所有的Resources都会有方法,例如非网络资源没有url和uri属性,默认方法就直接抛异常了,简单粗暴。举个栗子,不是所有的动物都会游泳,一只猪想游泳,先抛个异常给猪接着先。

2.resources里面有isOpen(),isReadAble()接口,这是个小技巧吧,类似与模版方法模式的钩子方法,也是很值得我们学习的。

org.springframework.core.io包内的源码分析的更多相关文章

  1. Java IO 之 FileInputStream & FileOutputStream源码分析

    Writer      :BYSocket(泥沙砖瓦浆木匠) 微         博:BYSocket 豆         瓣:BYSocket FaceBook:BYSocket Twitter   ...

  2. 关于Asp.net core配置信息读取的源码分析梳理

    概述 我们都知道asp.net core配置信息的读取离不开IConfigurationSource和IConfigurationProvider这两个类,ConfigurationSource可以提 ...

  3. spring源码分析-core.io包里面的类

    前些日子看<深入理解javaweb开发>时,看到第一章java的io流,发觉自己对io流真的不是很熟悉.然后看了下JDK1.7中io包的一点点代码,又看了org.springframewo ...

  4. springboot源码分析-SpringApplication

    SpringApplication SpringApplication类提供了一种方便的方法来引导从main()方法启动的Spring应用程序 SpringBoot 包扫描注解源码分析 @Spring ...

  5. Java集合源码分析(三)——LinkedList

    简介 LinkedList是一个链表结构的列表,也可以被作为堆栈.队列或双端队列使用.它继承于AbstractSequentialList双向链表,实现了List.Deque.Cloneable.ja ...

  6. org.springframework.core.io.ClassPathResource类

    测试代码 package cn.edu.hdu.pichen.springexample; import java.io.BufferedReader; import java.io.IOExcept ...

  7. cannot access org.springframework.core.io.InputStreamSouce

    cannot access org.springframework.core.io.InputStreamSouce错误,把mian路径下main.iml文件备份一下,然后删除该文件,报错就会消失,但 ...

  8. Spring源码分析-从@ComponentScan注解配置包扫描路径到IoC容器中的BeanDefinition,经历了什么(一)?

    阅前提醒 全文较长,建议沉下心来慢慢阅读,最好是打开Idea,点开Spring源码,跟着下文一步一步阅读,更加便于理解.由于笔者水平优先,编写时间仓促,文中难免会出现一些错误或者不准确的地方,恳请各位 ...

  9. 精尽Spring Boot源码分析 - 内嵌Tomcat容器的实现

    该系列文章是笔者在学习 Spring Boot 过程中总结下来的,里面涉及到相关源码,可能对读者不太友好,请结合我的源码注释 Spring Boot 源码分析 GitHub 地址 进行阅读 Sprin ...

随机推荐

  1. 解决VS2015中没有报表项(ReportViewer)的方法

    作者:何时.微笑成了种奢求 VS2015中没有报表项(ReportViewer),怎么办?这篇文章主要为大家详细介绍了解决VS2015中没有报表项(ReportViewer)的方法,感兴趣的小伙伴们可 ...

  2. node.js学习系列(一)

     node.js 百度百科简介 Node.js 是一个 Javascript 运行环境(runtime).实际上它是对 Google V8 引擎进行了封装.V8 引 擎执行 Javascript 的速 ...

  3. .NET CORE 学习笔记之安装EF【Microsoft.EntityFrameworkCore】扩展报错

    最近在学习.NET CORE ,刚开始就遇到问题了. 安装EF框架的试试就报错, 报错如下: 错误 程序包还原失败.正在回滚“XXX”的程序包更改. 找了好久的方案,网上也没搜到对应的问题和方案,然而 ...

  4. LVS之-LAMP搭建wordpress

    author:JevonWei 版权声明:原创作品 LVS搭建wordpress,涉及的知识点有DNS,LAMP,NFS及LVS 网络拓扑图 网络环境 NFS 192.168.198.130 mysq ...

  5. NET .NET深入体验和实战精要

    在学习.NET之前要充分理解基础,在这里将基础的知识点一一列举. 万丈高楼平地起 1.命名空间 命名空间是一种特殊的分类机制,他将与一个特定功能集有关的所有类型都分到一起,是.避免类名冲突的一种方式 ...

  6. 深入理解line-height

    什么是行间距? 古时候我们使用印刷机来出来文字.印刷出来的每个字,都位于独立的一个块中. 行间距,即传说中控制两行文字垂直距离的东东.在CSS中,line-height被用来控制行与行之间垂直距离. ...

  7. 微信小程序scroll标签的测试

    一:testscroll.wxml的代码如下.testview.js自动生成示例代码 //testscroll.wxml <view class="section__title&quo ...

  8. 201521123045 《Java程序设计》第8周学习总结

    第08周-集合与泛型 1. 本周学习总结 2. 书面作业 1.List中指定元素的删除(题目4-1)1.1 实验总结 答: Scanner实现字符串的输入有两种方法,一种是next(),一种nextL ...

  9. 201521123061 《Java程序设计》第五周学习总结

    201521123061 <Java程序设计>第五周学习总结 1. 本周学习总结 1.1 尝试使用思维导图总结有关多态与接口的知识点. 1.2 可选:使用常规方法总结其他上课内容. 1.代 ...

  10. 201521123006 《Java程序设计》第4周学习总结

    1. 本周学习总结 1.1 尝试使用思维导图总结有关继承的知识点. 1.2 使用常规方法总结其他上课内容. 本周除了继承,我们还重点学习了多态. (1)多态性在于有相同的形态,却是不同的行为或者说是不 ...