org.springframework.core.io.ClassPathResource位于Spring核心core下,用以表达类路径下的资源。
        首先简要说明一下什么是classpath,顾名思义,就是存放*.class类文件的路径,或者说ClassLoader加载类时为找到 *.class文件的路径。我们以一个WEB项目为例,发布后的目录结构大致如下:

然后以Tomcat为例,看一下WEB项目类加载时候的目录,参考 Tomcat Class Loader How-To 中的说明:

WebappX — A class loader is created for each web application that is deployed in a single Tomcat instance. All unpacked classes and resources in the /WEB-INF/classes directory of your web application, plus classes and resources in JAR files under the /WEB-INF/lib directory of your web application, are made visible to this web application, but not to other ones.

因此,对于部署在Tomcat上的WEB应用来说,/WEB-INF/classes和/WEB-INF/lib目录就是我们所指的classpath。

ClassPathResource是org.springframework.core.io.Resource接口的实现类。可以使用ClassLoader或Class类加载资源。支持转换为java.io.File对象(在Jar文件中的资源除外)。其继承实现关系图如下:

ClasspathResource类的属性变量和构造方法如下:

 private final String path;@Nullableprivate ClassLoader classLoader;// 通过ClassLoader加载资源文件@Nullableprivate Class<?> clazz; // 通过Class类加载资源文件// 通过类路径创建resourcepublic ClassPathResource(String path){...}// 通过类路径和给定的ClassLoader创建resourcepublic ClassPathResource(String path, @Nullable ClassLoader classLoader){...}// 通过类路径和给定的Class类创建resourcepublic ClassPathResource(String path, @Nullable Class<?> clazz){...}// 通过类路径和给定的ClassLoader或Class创建resourceprotected ClassPathResource(String path, @Nullable ClassLoader classLoader, @Nullable Class<?> clazz){...}

在类继承关系中,每个类定义的方法如下:

Resource AbstractResource AbstractFileResolvingResource ClassPathResource
对底层资源的抽象描述
比如文件或类路径资源
对资源接口描述的基础实现
预先实现特定的行为
将URL解析为文件资源引用的抽象基类,尤其对JBOOS的vfs文件协议的支持 类路径资源的Resource实现
boolean exists()
判断该资源是否存在
public boolean exists()
实现父接口方法,检查资源(文件或目录)File对象或资源(文件)InputStream对象是否打开
public boolean exists()
重写父类方法,getURL后如果URL的文件协议是file:vfsfile:vfs则返回getFile().exists()直接判断该文件是否存在,如果非上述文件协议则尝试判断是否网络资源,通过HTTP请求看是否返回HTTP Status-Code=200,如果扔非上述,则尝试getInputStream().close()看文件流是否可打开
public boolean exists()
重写父类方法,判断是否能获取到该资源的URL对象
boolean isReadable()
是否可通过InputStreamSource.getInputStream()读取,这里注意返回true仍然可能读取失败,但返回false一定是不能读取
默认返回exists()
public boolean isReadable()
实现父接口方法,该方法在当资源存在的情况下始终返回true,返回值与父接口方法中定义的默认返回值一致,即返回exists()
public boolean isReadable()
重写父类方法,getURL后如果URL的文件协议是file:vfsfile:vfs则getFile得到该资源File对象,判断该File资源是否非目录且canRead可读,如果非上述文件协议则尝试调用网络资源,判断是否可成功调用且返回内容长度大于0,如果扔非上述,则尝试getInputStream().close()看文件流是否可打开
boolean isOpen()
表明该资源是否有打开的stream流,如果返回true则InputStream无法多次读取,且读完之后关闭流以防止内存泄露
默认返回false
public boolean isOpen()
实现父接口方法,与接口方法中定义的默认返回值一致,即始终返回false
boolean isFile()
判断该文件是否是系统文件中的文件,true值表示(但不保证)可以成功调用getFile()方法
默认返回false
public boolean isFile()
实现父接口方法,与接口方法中定义的默认返回值一致,即始终返回false
public boolean isFile()
重写父类方法,getURL后如果url为vfs开头协议(vfs/vfsfile)则交给VfsResourceDelegate类判断,如果url为file协议则返回true
protected boolean isFile(URI uri)
重载isFile方法,根据指定的URI判断该资源是否是一个文件引用,如果URI的scheme以vfs开头则交给VfsResourceDelegate类判断,否则判断如果URI的scheme等于file则返回true
URL getURL()
返回该资源对应的URL
public URL getURL()
实现父接口方法,这里假设资源不能解析为URL,直接返回了FileNotFoundException异常
public URL getURL()
重写父类方法,根据类路径参数获取该资源的URL对象
URI getURI()
返回该资源对应的URI
public URI getURI()
实现父接口方法,基于getURL返回的URL构建一个URI
File getFile()
返回该资源的File对象
public File getFile()
实现父接口方法,这里假设资源无法解析为文件绝对路径,直接返回了FileNotFoundException异常
public File getFile()
重写父类方法,父类直接返回FileNotFoundException异常,在这里通过getURL获取到URL对象(具体URL由其子类确定,比如ClasspathResource重写了getURL通过类加载器获取到了类路径资源的URL),如果url为vfs开头协议(vfs/vfsfile)则交给VfsResourceDelegate类获取File对象,否则通过得到url获取File对象
protected File getFile(URI uri)
重载getFile方法,根据指定的URI获取资源File对象,如果URI的scheme以vfs开头则交给VfsResourceDelegate类获取
ReadableByteChannel readableChannel()
默认返回Channels.newChannel(getInputStream())
public ReadableByteChannel readableChannel()
实现父接口方法,与父接口的默认返回值相同
public ReadableByteChannel readableChannel()
根据指定的URI调用FileChannel.open 返回一个ReadableByteChannel对象
long contentLength()
返回该资源内容的长度
public long contentLength()
根据getInputStream()返回的InputStream,读取并计算资源的内容长度
public long contentLength()
根据getURL获得URL对象,如果是文件(file/vfsfile/vfs)URL返回文件长度,否则尝试网络连接获取资源并返回长度
long lastModified()
返回该资源最后一次修改的时间戳
public long lastModified()
获取并返回该资源文件的时间戳
public long lastModified()
根据getURL获取URL对象,如果是文件(file/vfsfile/vfs)或归档文件(jar/war/zip/vfszip/wsjar)则获取文件的最后修改时间戳,否则获取网络连接并获取最后修改时间戳
Resource createRelative(String relativePath)
根据相对于该资源的相对路径,创建一个Resource资源,比如classpath资源目录conf下有A.xml和B.xml,Resource a = new ClassPathResource("conf/A.xml"); 那么在创建b资源的时候就可以以a为参照Resource b = a.createRelative("B.xml");
public Resource createRelative(String relativePath)
实现父接口方法,这里假设改相对资源未被创建,直接返回了FileNotFoundException异常
public Resource createRelative(String relativePath)
重写父类方法,根据参照资源的类路径得到relativePath参数的真实classpath路径,并创建Resource资源对象
String getFilename()
返回该资源的文件名,通常是路径的最后一部分,比如:myfile.txt
public String getFilename()
实现父接口方法,这里假设该资源无文件名,直接返回了null
public String getFilename()
重写父类方法,根据classpath截取后面的文件名并返回
String getDescription()
返回该资源的描述,用于该资源在处理时的错误输出
public String getDescription()
重写父类方法,返回格式如class path resource [...]的内容
protected File getFileForLastModifiedCheck()
获取用于时间戳检查的文件,这里默认返回了getFile()
protected File getFileForLastModifiedCheck()
重写父类方法,扩展了父类方法,在getFile之前先判断url协议是否为jar/war/zip/vfszip/wsjar,如果是则获取最外层的文件URL对应的File对象,比如嵌套在war中的jar文件,则返回war文件File对象。这里判断vfs开头协议扔交给VfsResourceDelegate类来处理
public boolean equals(Object other)
重写Object的equals方法,用于比较两个Resource的Description是否相同
public boolean equals(Object other)
重写Object方法,比较类路径的值是否相同
public int hashCode()
重写Object的hashCode方法,用于获取Resource的Description值的hashCode值
public int hashCode()
重写Object方法,获取类路径classpath的hashCode值
public String toString()
重写Object的toString方法,返回Resource的Description信息
public final String getPath()
返回该资源的classpath,构造函数的path参数经过规范化处理的结果
public final ClassLoader getClassLoader()
如果指定了Class,则通过该Class获取ClassLoader,否则返回属性变量的ClassLoader参数
public InputStream getInputStream()
Resource继承了InputStreamSource接口,在ClassPathResource中得到了具体的实现,根据资源路径得到文件流

在AbstractFileResolvingResource类中由于增加了对JBOOS的vfs文件协议的支持,因此包含了一个`VfsResourceDelegate`内部类用于获取`VfsResource`类型资源对象,该资源对象同样继承自`AbstractResource`抽象类,并针对vfs文件的特点对方法进行了重写。如下:

/*** Inner delegate class, avoiding a hard JBoss VFS API dependency at runtime.*/
private static class VfsResourceDelegate {public static Resource getResource(URL url) throws IOException {return new VfsResource(VfsUtils.getRoot(url));}public static Resource getResource(URI uri) throws IOException {return new VfsResource(VfsUtils.getRoot(uri));}
}

ClassPathResource的使用:

Resource resource = new ClassPathResource("conf/custom-beans.xml");

参数path应在类路径下能够被ClassLoader所加载。

获取到了Resource对象也就等于获取到了该资源文件,后面可以根据方法的定义对文件进行相关操作。

System.out.println(resource.getURL());
System.out.println(resource.getFilename());
System.out.println(resource.getFile().getPath());
// ... ....

Spring ClassPathResource详解相关推荐

  1. Spring入门详解

    typora-copy-images-to: upload Spring入门详解 Spring框架是Java开发中最常用的框架,功能非常强大 源码下载:Spring Framework jar包.文档 ...

  2. Spring AOP详解(转载)所需要的包

    上一篇文章中,<Spring Aop详解(转载)>里的代码都可以运行,只是包比较多,中间缺少了几个相应的包,根据报错,几经百度搜索,终于补全了所有包. 截图如下: 在主测试类里面,有人怀疑 ...

  3. Spring JDBC详解

    <Spring JDBC详解> 本文旨在讲述Spring JDBC模块的用法.Spring JDBC模块是Spring框架的基础模块之一. 一.概述 在Spring JDBC模块中,所有的 ...

  4. Spring 体系结构详解

    Spring 体系结构详解 核心容器(Core Container) Core和Beans模块提供了Spring最基础的功能,提供IOC和依赖注入特性.这里的基础概念是BeanFactory,它提供对 ...

  5. [转载]Spring配置文件详解一:

    2019独角兽企业重金招聘Python工程师标准>>> 原文地址:Spring配置文件详解一:<context:annotation-config/>与<conte ...

  6. struts2+hibernate+spring配置详解

    #struts2+hibernate+spring配置详解 struts2+hibernate+spring配置详解 哎 ,当初一个人做好难,现在终于弄好了,希望自学这个的能少走些弯路. 以下是自己配 ...

  7. spring注解详解与用法(总览)

    这篇文章收集了我写的所有的spring注解的详细说明与用法,点击可以跳转到对应文章,此文章会不断更新 spring注解详解与用法(1)最基础也是最常见的如下所示,详情点击这里 @Controller/ ...

  8. Spring IoC详解

    Spring IoC详解 原文地址:Spring IoC详解 写在最前 本文将主要写Spring最核心的部分,为什么写这篇的原因也是因为在刚开始学习Spring的时候,学得太粗糙了.感觉学了个皮毛,从 ...

  9. Spring源码(八):Spring事务详解

    Spring事务详解 一.事务执行流程 二.Spring事务切面 三.事务切面的Pointcut和Advice 四.注解事务的源码分析 五.Sping事务的传播属性 六.Sping事务的异常校验 七. ...

  10. Spring核心技术详解

    一.Sring简介 Spring是一个分层的Java SE/EE应用一站式的轻量级开源框架.Spring核心是IOC和AOP.  Spring主要优点包括: 方便解耦,简化开发,通过Spring提供的 ...

最新文章

  1. 转载:asp.net生成缩略图通用函数(支持多种生成方式)
  2. 分式的二阶导数怎么求_为何二阶微分要记为 d²y/dx²?
  3. 蓝桥杯 - 序列计数(记忆化搜索)
  4. HTML---HTML简介
  5. 安川伺服总线通讯方式_MⅢ总线特点 安川伺服选型与应用案例
  6. php index.php 文件路径,自研 PHP 框架 1.0_index.php 文件说明
  7. Django之model补充:一对多、跨表操作
  8. cocos2dx 3.0 windows平台 中文乱码解决
  9. [react] 在React中你有经常使用常量吗?
  10. 【Python CheckiO 题解】Largest Rectangle in a Histogram
  11. IntelliJ Idea取消Could not autowire. No beans of 'xxxx' type found的错误提示
  12. 伪静态页面在iis7.0中的配置
  13. QPainter绘制方法
  14. 关于Unity资源包导入项目后版本不匹配问题
  15. php扩展 zval_copy_ctor,Zend API:pval/zval 数据结构
  16. 老罗与西门子的公关战争
  17. 电子计算机是汉字的掘墓人,当人类社会进入到信息时代,曾有人_______,计算机是方块汉字的掘墓人。然 - 问答库...
  18. word文档转化html 工具mammoth
  19. 火车运输java_基于jsp的火车售票-JavaEE实现火车售票 - java项目源码
  20. android串口编程实例_PLC编程由浅到深 | 如何搞懂西门子PLC脉冲输出

热门文章

  1. 基于Python的A-Priori算法发现购物篮关联规则
  2. 教育行业是永恒不过时的常青藤行业!
  3. Win10电脑系统使用技巧
  4. 自考深圳大学本科难吗?亲身经历分享
  5. 10.16 Loi队内胡策 贪心+毒瘤输入+DP+数论
  6. JavaWeb课堂笔记
  7. day002血字的研究
  8. USRPx310的射频板UBX160
  9. FTM的PWM、输入捕获、正交解码
  10. 如何简单理解ngnix的反向代理