版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/ljz2016/article/details/82662316
在Java中,将不同来源的资源抽象成URL,通过注册不同的handler来处理不同 的资源(“file,http,jar”)等,URL没有默认相对于”classpath:“或ServletContext等资源的handler,因此spring对其内部使用的资源实现了自己的抽象结构:Resource接口来封装底层资源。
Resouce接口提供了File、url、uri的转换。提供getDescription用于在错误处理中打印信息。
类继承层次图:
类名 | 作用 |
---|---|
InputStreamSource | 定义了获取InputStream的方法 |
Resource | 定义了资源属性的获取方法 |
AbstractResource | 对Resource方法做了实现 |
AbstractFileResolvingResource | 对AbstractResource 的方法做了覆盖 |
ClassPathResource | 着重实现了InputStreamSource 的方法 |
定义了3个成员变量:
private final String path;
private ClassLoader classLoader;
private Class<?> clazz;
构造方法
public ClassPathResource(String path) {
this(path, (ClassLoader)null);
}
public ClassPathResource(String path, ClassLoader classLoader) {
Assert.notNull(path, "Path must not be null");
String pathToUse = StringUtils.cleanPath(path);
if(pathToUse.startsWith("/")) {
pathToUse = pathToUse.substring(1);
}
this.path = pathToUse;
this.classLoader = classLoader != null?classLoader:ClassUtils.getDefaultClassLoader();
}
public ClassPathResource(String path, Class<?> clazz) {
Assert.notNull(path, "Path must not be null");
this.path = StringUtils.cleanPath(path);
this.clazz = clazz;
}
protected ClassPathResource(String path, ClassLoader classLoader, Class<?> clazz) {
this.path = StringUtils.cleanPath(path);
this.classLoader = classLoader;
this.clazz = clazz;
}
核心方法:
//获取文件资源的输入流,路径是基于classpath的
public InputStream getInputStream() throws IOException {
InputStream is;
if(this.clazz != null) {
is = this.clazz.getResourceAsStream(this.path);
} else if(this.classLoader != null) {
is = this.classLoader.getResourceAsStream(this.path);
} else {
is = ClassLoader.getSystemResourceAsStream(this.path);
}
if(is == null) {
throw new FileNotFoundException(this.getDescription() + " cannot be opened because it does not exist");
} else {
return is;
}
}
//基于当前文件所在位置,创建相关的资源
public Resource createRelative(String relativePath) {
String pathToUse = StringUtils.applyRelativePath(this.path, relativePath);
return this.clazz != null?new ClassPathResource(pathToUse, this.clazz):new ClassPathResource(pathToUse, this.classLoader);
}
//获取文件位置的描述信息
public String getDescription() {
StringBuilder builder = new StringBuilder("class path resource [");
String pathToUse = this.path;
if(this.clazz != null && !pathToUse.startsWith("/")) {
builder.append(ClassUtils.classPackageAsResourcePath(this.clazz));
builder.append('/');
}
if(pathToUse.startsWith("/")) {
pathToUse = pathToUse.substring(1);
}
builder.append(pathToUse);
builder.append(']');
return builder.toString();
}