In Java, resources from different sources are abstracted into URLs, and different resources ("file,http,jar") are processed by registering different handlers. By default, URLs do not have handlers relative to resources such as "classpath:" or ServletContext. Therefore, spring implements its own abstract structure for resources used internally: Resource interface to encapsulate the underlying resources.
The resource interface provides the transformation of File, url and uri. Provide getDescription to print information in error handling.
Class inheritance hierarchy:
Class name | Effect |
---|---|
InputStreamSource | The method of getting InputStream is defined |
Resource | The method of getting resource attributes is defined |
AbstractResource | Implement the Resource method |
AbstractFileResolvingResource | Overriding the AbstractResource method |
ClassPathResource | The method of InputStreamSource is emphasized |
Three member variables are defined:
private final String path;
private ClassLoader classLoader;
private Class<?> clazz;
Construction method
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;
}
Core approach:
//Get the input stream of the file resource. The path is based on the 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;
}
}
//Create related resources based on the location of the current file
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);
}
//Get description of file location
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();
}