AbstractResource学习

AbstractResource实现了Resource的大部分方法,下面逐个方法解析一下:

1.

/**

* This implementation checks whether a File can be opened,

* falling back to whether an InputStream can be opened.

* This will cover both directories and content resources.

*/

public boolean exists() {

// Try file existence: can we find the file in the file system?

try {

return getFile().exists();

}

catch (IOException ex) {

// Fall back to stream existence: can we open the stream?

try {

InputStream is = getInputStream();

is.close();

return true;

}

catch (Throwable isEx) {

return false;

}

}

}

注释的意思是这方法主要用来判断所请求资源是否存在(包括当前资源和本地主机上的路径资源,不存在包括资源有无和是否可以被打开)

方法内部,return getFile().exists();getFile()方法抛出了一个受查异常FileNotFoundException(getDescription() + " cannot be resolved to absolute file path");发生异常抛出后会进入本方法的catch块,关闭Inputstream如果没有成功返返回一个false,返回外层异常,抛出一个笼统的IOException。

第二个方法

/**

* This implementation always returns <code>true</code>.

*/

public boolean isReadable() {

return true;

}

注释写着本方法永远返回true,小心求证,该类的直接父接口Resource,关于exists()方法如下:

/**

* Return whether the contents of this resource can be read,

* e.g. via {@link #getInputStream()} or {@link #getFile()}.

* <p>Will be <code>true</code> for typical resource descriptors;

* note that actual content reading may still fail when attempted.

* However, a value of <code>false</code> is a definitive indication

* that the resource content cannot be read.

* @see #getInputStream()

*/

boolean isReadable();

看了注释,里面的 note that actual content reading may still fail when attempted.这句话是说不管怎样这个方法无法控制都容易失败,Juergen Hoeller肯能觉得io的决定因素很多,所以就懒得实现这个方法了吧,在讨论方法中一律返回true。

第三个方法:

/**

* This implementation always returns <code>false</code>.

*/

public boolean isOpen() {

return false;

}

和上面的方法不同,永远返回false,用上一个方法的结局思路看Resource接口中的方法注释。

/**

* Return whether this resource represents a handle with an open

* stream. If true, the InputStream cannot be read multiple times,

* and must be read and closed to avoid resource leaks.

* <p>Will be <code>false</code> for typical resource descriptors.

*/

boolean isOpen();

看到了,方法说如果输入流打开,就不能使用,必须要关闭避免资源泄露。作者假定一切顺利,如果发生异常,可能会在别的方法内处理。

4.第四个方法

/**

* This implementation throws a FileNotFoundException, assuming

* that the resource cannot be resolved to a URL.

*/

public URL getURL() throws IOException {

throw new FileNotFoundException(getDescription() + " cannot be resolved to URL");

}

假设发生错误就抛出异常。

5.第五个方法

/**

* This implementation builds a URI based on the URL returned

* by {@link #getURL()}.

*/

public URI getURI() throws IOException {

URL url = getURL();

try {

return ResourceUtils.toURI(url);

}

catch (URISyntaxException ex) {

throw new NestedIOException("Invalid URI [" + url + "]", ex);

}

}

这个实现会根据资源描述符建立一个资源定位符,具体分析方法。

URL url = getURL();获取URL();

try {

return ResourceUtils.toURI(url);

}

catch (URISyntaxException ex) {

throw new NestedIOException("Invalid URI [" + url + "]", ex);

}

方法不能完成捕获基本的net包内异常URISyntaxException资源定位符表达式异常,抛出的是Spring的自定义异常,NestedIOException。

6.第六个方法

/**

* This implementation throws a FileNotFoundException, assuming

* that the resource cannot be resolved to an absolute file path.

*/

public File getFile() throws IOException {

throw new FileNotFoundException(getDescription() + " cannot be resolved to absolute file path");

}

这个方法在获得文件错误时抛出文件找不到异常哈哈。

7.第七个方法

/**

* This implementation reads the entire InputStream to calculate the

* content length. Subclasses will almost always be able to provide

* a more optimal version of this, e.g. checking a File length.

* @see #getInputStream()

*/

public long contentLength() throws IOException {

InputStream is = getInputStream();

try {

long size = 0;

byte[] buf = new byte[255];

for (int read = is.read(buf); read != -1;) {

size += read;

}

return size;

}

finally {

try {

is.close();

}

catch (IOException ex) {

}

}

}

这个方法根据以后各种实现getInputStream的类来计算输入的内容长度long。哈哈】

8.第八个方法

/**

* This implementation checks the timestamp of the underlying File,

* if available.

* @see #getFileForLastModifiedCheck()

*/

public long lastModified() throws IOException {

long lastModified = getFileForLastModifiedCheck().lastModified();

if (lastModified == 0L) {

throw new FileNotFoundException(getDescription() +

" cannot be resolved in the file system for resolving its last-modified timestamp");

}

return lastModified;

}

这个方法检查资源的最后修改时间,里面的getFileForLastModifiedCheck()需要一看,如下:

/**

* Determine the File to use for timestamp checking.

* <p>The default implementation delegates to {@link #getFile()}.

* @return the File to use for timestamp checking (never <code>null</code>)

* @throws IOException if the resource cannot be resolved as absolute

* file path, i.e. if the resource is not available in a file system

*/

protected File getFileForLastModifiedCheck() throws IOException {

return getFile();

}

这个图方法调用getFile(),就回去,调用File类中的lastModified(),这个方法解释了一下getFile()抛出异常的情况,两种一个是不是绝对路径抛出,也就是对于系统来说无效的路径。

9.第九个方法

/**

* This implementation throws a FileNotFoundException, assuming

* that relative resources cannot be created for this resource.

*/

public Resource createRelative(String relativePath) throws IOException {

throw new FileNotFoundException("Cannot create a relative resource for " + getDescription());

}

相关资源不能被创建就抛出异常,文件找不到。

10.第十个方法

/**

* This implementation always returns <code>null</code>,

* assuming that this resource type does not have a filename.

*/

public String getFilename() throws IllegalStateException {

return null;

}

这个方法通常返回null,假定资源无名。

11.第十一个方法

/**

* This implementation returns the description of this resource.

* @see #getDescription()

*/

@Override

public String toString() {

return getDescription();

}

调用getDescription();这个方法在哪?在实现类里面,各个实现初始化的时候都会填充description【String】。

12.第十二个方法

/**

* This implementation compares description strings.

* @see #getDescription()

*/

@Override

public boolean equals(Object obj) {

return (obj == this ||

   (obj instanceof Resource && ((Resource) obj).getDescription().equals(getDescription())));

}

这个equals方法写的很牛逼!!!!!!!!!!!!判断参数的地址,判断参数的父类(接口也是类),如果是强转,调用description()【实现类实现】,判断描述,调用原始的equals方法。也就是两种情况,就是一个对象,或者描述一致,就认为是一个资源,这种情况我存在疑问,可能框架会限制Resource的单例。。。。

最后一个方法

/**

* This implementation returns the description's hash code.

* @see #getDescription()

*/

@Override

public int hashCode() {

return getDescription().hashCode();

}

简单的返回hashcode。

至此AbstractResource抽象类解释完毕,有一些心得。

最上层接口持有一个公共抽象方法,此方法在其子接口内被反复使用,但会根据具体实现去使用,这样具体实现上有一个抽象类,不去实现这个重要方法,简洁的有一种美感。

 

转载于:https://my.oschina.net/stuspring/blog/471230

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值