今天来分析Spring的资源接口Resource的各个实现类。关于它的接口和抽象类,参见上一篇博文——Spring源码分析——资源访问利器Resource之接口和抽象类分析
一、文件系统资源 FileSystemResource
文件系统资源 FileSystemResource,资源以文件系统路径的方式表示。这个类继承自AbstractResource,并实现了写的接口WritableResource。类全称为public class FileSystemResource extends AbstractResource implements WritableResource 。这个资源类是所有Resource实现类中,唯一一个实现了WritableResource接口的类。就是说,其他的类都不可写入操作,都只能读取。部分翻译注释后,源码如下:(以后不重要的源码我就折叠起来)
/* * Copyright 2002-2012 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.core.io; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.URI; import java.net.URL; import org.springframework.util.Assert; import org.springframework.util.StringUtils; /** * @author Juergen Hoeller * @since 28.12.2003 * @see java.io.File */ public class FileSystemResource extends AbstractResource implements WritableResource { private final File file; // 不可变属性 private final String path; // 不可变属性 public FileSystemResource(File file) { // 简单的构造方法,path为file路径格式化后的样子 Assert.notNull(file, "File must not be null"); this.file = file; this.path = StringUtils.cleanPath(file.getPath()); } public FileSystemResource(String path) { //简单的构造方法 Assert.notNull(path, "Path must not be null"); this.file = new File(path); this.path = StringUtils.cleanPath(path); } public final String getPath() { //新增的方法,返回资源路径,方法不可重写 return this.path; } @Override public boolean exists() { return this.file.exists(); } @Override public boolean isReadable() { return (this.file.canRead() && !this.file.isDirectory()); } public InputStream getInputStream() throws IOException { //InputStreamSource接口的实现方法 return new FileInputStream(this.file); } @Override public URL getURL() throws IOException { //可见这个url是通过uri得到的 return this.file.toURI().toURL(); } @Override public URI getURI() throws IOException { return this.file.toURI(); } @Override public File getFile() { return this.file; } @Override public long contentLength() throws IOException { return this.file.length(); } @Override public Resource createRelative(String relativePath) { String pathToUse = StringUtils.applyRelativePath(this.path, relativePath); return new FileSystemResource(pathToUse); } @Override public String getFilename() { return this.file.getName(); } public String getDescription() { // 资源描述,直接用绝对路径来构造 return "file [" + this.file.getAbsolutePath() + "]"; } public boolean isWritable() { // WritableResource接口的实现方法 return (this.file.canWrite() && !this.file.isDirectory()); } public OutputStream getOutputStream() throws IOException { return new FileOutputStream(this.file); } @Override public boolean equals(Object obj) { //通过path来比较 return (obj == this || (obj instanceof FileSystemResource && this.path.equals(((FileSystemResource) obj).path))); } @Override public int hashCode() { // 文件资源的HashCode就是path的hashCode return this.path.hashCode(); } }