转载

Spring源码分析之Resource

基于Spring1.0

public interface InputStreamSource{

 InputStream getInputStream() throws IOException;

}

public interface Resource extends InputStreamSource{
 boolean exists();
 boolean isOpen();
 URL getURL() throws IOException;
 File getFile() throws IOException;
 String getDescription();
}


public abstract class AbstractResource implements Resource{

 protected static final String URL_PROTOCOL_FILE = "file";

 @Override
 public boolean exists(){
 try {
 return getFile().exists();
 }
 catch (IOException ex) {
 try {
 InputStream is = getInputStream();
 is.close();
 return true;
 }
 catch (IOException ex2) {
 return false;
 }
 }
 }

 @Override
 public boolean isOpen(){
 return false;
 }
 /**
* 如果实现类重写该方法,则使用子类,如果没有重写,则表示子类不支持该方法,抛出异常
*/
 @Override
 public URL getURL() throws IOException{
 throw new FileNotFoundException(getDescription() + " cannot be resolved to URL");
 }

 /**
* 如果实现类重写该方法,则使用子类,如果没有重写,则表示子类不支持该方法,抛出异常
*/
 @Override
 public File getFile() throws IOException{
 throw new FileNotFoundException(getDescription() + " cannot be resolved to absolute file path");
 }


 @Override
 public String toString(){
 return getDescription();
 }


 @Override
 public boolean equals(Object obj){
 return (obj instanceof Resource && ((Resource) obj).getDescription().equals(getDescription()));
 }


 @Override
 public int hashCode(){
 return getDescription().hashCode();
 }

}



public class ClassPathResource extends AbstractResource{

 private final String path;

 private Class clazz;


 public ClassPathResource(String path){
 // /开头表示绝对路径
 if (path.startsWith("/")) {
 path = path.substring(1);
 }
 this.path = path;
 }


 public ClassPathResource(String path, Class clazz){
 this.path = path;
 this.clazz = clazz;
 }

 @Override
 public InputStream getInputStream() throws IOException{
 InputStream is = null;
 if (this.clazz != null) {
 is = this.clazz.getResourceAsStream(this.path);
 } else {
 ClassLoader ccl = Thread.currentThread().getContextClassLoader();
 is = ccl.getResourceAsStream(this.path);
 }
 if (is == null) {
 throw new FileNotFoundException("Could not open " + getDescription());
 }
 return is;
 }

 @Override
 public URL getURL() throws IOException{
 URL url = null;
 if (this.clazz != null) {
 url = this.clazz.getResource(this.path);
 } else {
 ClassLoader ccl = Thread.currentThread().getContextClassLoader();
 url = ccl.getResource(this.path);
 }
 if (url == null) {
 throw new FileNotFoundException(getDescription() + " cannot be resolved to URL " +
 "because it does not exist");
 }
 return url;
 }

 @Override
 public File getFile() throws IOException{
 URL url = getURL();
 if (!URL_PROTOCOL_FILE.equals(url.getProtocol())) {
 throw new FileNotFoundException(getDescription() + " cannot be resolved to absolute file path " +
 "because it does not reside in the file system: URL=[" + url + "]");
 }
 return new File(URLDecoder.decode(url.getFile()));
 }

 @Override
 public String getDescription(){
 return "class path resource [" + this.path + "]";
 }

}

AbstractResource主要实现了两个方法,exists()和 isOpen(), exists方法先通过文件判断资源是否存在,然后根据InputStream进行判断。isOpen()返回false

getURL() ,getFile() 在这里不是抽象方法的原因是因为: 如果实现类重写该方法,则使用子类,如果没有重写,则表示子类不支持该方法,直接抛出异常,避免在实现类中,命名和该方法没关联,还需要抛出异常

比如ClassPathResource重写, InputStreamReSource

原文  http://liuyiyou.cn/2018-02-10-Spring源码分析之Resource/
正文到此结束
Loading...