打算补下基础,学习下Spring源码,参考书籍是《Spring源码深度解析》,使用版本是Spring 3.2.x,本来想试图用脑图记录的,发现代码部分不好贴,还是作罢,这里只大略记录下想法,不写太细了
类图如上,
文件结构图如上。
可以看到 这些都在IO目录下,帮助类集中存在support目录下。最根级的接口是InputStreamSource,只有getInputStream()一个方法,在类中说明了,这是用来获取InputStream的,期望每次调用都返回新的stream。没有单纯实现这个接口的类,不太清楚为什么只是单独提出来做接口。
Resource作为继承的子类,多定义了很多方法
这些方法在AbstractResource都有了默认实现
public boolean exists() {
// Try file existence: can we find the file in the file system?
try {
return getFile().exists();
}
catch (IOException ex) {
// Fall back to stream existence: can we open the stream?
try {
InputStream is = getInputStream();
is.close();
return true;
}
catch (Throwable isEx) {
return false;
}
}
}
先用获得文件判断是否存在,获得文件的过程中的IOException 再试图获取流,这个过程还可能抛错,如果获取文件过程中虽然有抛错,但是获取流成功了,也算成功,算是一种双保险,英文里叫Fall back,这里面的getFile在本类中有个 方法,直接抛错,到子类里去实现。随便找两个实现看看。
先看比较简单的,getFile直接返回成员变量file,file由构造器初始化。
ClassPathResource中没找到getFile,原来在父类的AbstractFileResolvingResource中, 可以看到他使用了ResourceUtils的工具类的获取方法。AbstractFileResolvingResource方法里用了很多getURL方法,但是都没有具体实现,实现都在子类里,感觉 绕来绕去的
再看类介绍,这个类是用来把URI转成File类的中间抽象类,这样大概可以看出,最上面那张图真的是不同层级的抽象 FileSystemResource因为直接能拿到file,所很简单,直接继承就行了,classpath,sevletcontext,因为不是实际的File,加了层url的转换,他们获取url的方式不同,所以在子类里实现,但是从url转到file又是相通的,所以在父类实现。其他功能则从工具类里获得。
关于这个toURI方法,可以看这个链接
https://blog.csdn.net/zunguitiancheng/article/details/79196598
这样转了一圈,上面图里很多类都看了,还有WritableResource ,这个类是FileSystemResource ,表示可写,所以有输出流。另外ContextResource的子类在web包里。
ps idea的 alt+7的structure视图,纵观方法很好用
参考文章 :https://www.cnblogs.com/zrtqsk/p/4015985.html 这篇讲的很细,很值得看 关于ClassPathResource的可以进去看