基于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