/*
 * 用一个给定的类加载器或者给定的类来加载资源
 */
public class ClassPathResource extends AbstractFileResolvingResource {

	private final String path;

	private ClassLoader classLoader;

	private Class<?> clazz;

	/**
	 * Create a new {@code ClassPathResource} for {@code ClassLoader} usage.
	 * A leading slash will be removed, as the ClassLoader resource access
	 * methods will not accept it.
	 * <p>The thread context class loader will be used for
	 * loading the resource.
	 * @param path the absolute path within the class path
	 * @see java.lang.ClassLoader#getResourceAsStream(String)
	 * @see org.springframework.util.ClassUtils#getDefaultClassLoader()
	 */
	//类路径的决定路径
	public ClassPathResource(String path) {
		this(path, (ClassLoader) null);
	}

	/**
	 * Create a new {@code ClassPathResource} for {@code ClassLoader} usage.
	 * A leading slash will be removed, as the ClassLoader resource access
	 * methods will not accept it.
	 * @param path the absolute path within the classpath
	 * @param classLoader the class loader to load the resource with,
	 * or {@code null} for the thread context class loader
	 * @see ClassLoader#getResourceAsStream(String)
	 */
	//创建一个类路径资源给类加载器使用
	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());//获得默认的类加载器
	}

	/**
	 * Create a new {@code ClassPathResource} for {@code Class} usage.
	 * The path can be relative to the given class, or absolute within
	 * the classpath via a leading slash.
	 * @param path relative or absolute path within the class path
	 * @param clazz the class to load resources with
	 * @see java.lang.Class#getResourceAsStream
	 */
	public ClassPathResource(String path, Class<?> clazz) {
		Assert.notNull(path, "Path must not be null");
		this.path = StringUtils.cleanPath(path);
		this.clazz = clazz;
	}

	/**
	 * Create a new {@code ClassPathResource} with optional {@code ClassLoader}
	 * and {@code Class}. Only for internal usage.
	 * @param path relative or absolute path within the classpath
	 * @param classLoader the class loader to load the resource with, if any
	 * @param clazz the class to load resources with, if any
	 */
	protected ClassPathResource(String path, ClassLoader classLoader, Class<?> clazz) {
		this.path = StringUtils.cleanPath(path);
		this.classLoader = classLoader;
		this.clazz = clazz;
	}

	/**
	 * Return the path for this resource (as resource path within the class path).
	 */
	//返回资源路径
	public final String getPath() {
		return this.path;
	}

	/**
	 * Return the ClassLoader that this resource will be obtained from.
	 */
	//这个资源得到的类加载器
	public final ClassLoader getClassLoader() {
		return (this.clazz != null ? this.clazz.getClassLoader() : this.classLoader);
	}

	/**
	 * This implementation checks for the resolution of a resource URL.
	 * @see java.lang.ClassLoader#getResource(String)
	 * @see java.lang.Class#getResource(String)
	 */
	@Override
	public boolean exists() {
		return (resolveURL() != null);
	}

	/**
	 * Resolves a URL for the underlying class path resource.
	 * @return the resolved URL, or {@code null} if not resolvable
	 */
	//返回潜在的class 路径资源URL
	protected URL resolveURL() {
		if (this.clazz != null) {
			return this.clazz.getResource(this.path);
		}
		else if (this.classLoader != null) {
			return this.classLoader.getResource(this.path);
		}
		else {
			return ClassLoader.getSystemResource(this.path);
		}
	}

	/**
	 * This implementation opens an InputStream for the given class path resource.
	 * @see java.lang.ClassLoader#getResourceAsStream(String)
	 * @see java.lang.Class#getResourceAsStream(String)
	 */
	//
	@Override
	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(getDescription() + " cannot be opened because it does not exist");
		}
		return is;
	}

	/**
	 * This implementation returns a URL for the underlying class path resource,
	 * if available.
	 * @see java.lang.ClassLoader#getResource(String)
	 * @see java.lang.Class#getResource(String)
	 */
	@Override
	public URL getURL() throws IOException {
		URL url = resolveURL();
		if (url == null) {
			throw new FileNotFoundException(getDescription() + " cannot be resolved to URL because it does not exist");
		}
		return url;
	}

	/**
	 * This implementation creates a ClassPathResource, applying the given path
	 * relative to the path of the underlying resource of this descriptor.
	 * @see org.springframework.util.StringUtils#applyRelativePath(String, String)
	 */
	@Override
	public Resource createRelative(String relativePath) {
		String pathToUse = StringUtils.applyRelativePath(this.path, relativePath);
		return new ClassPathResource(pathToUse, this.classLoader, this.clazz);
	}

	/**
	 * This implementation returns the name of the file that this class path
	 * resource refers to.
	 * @see org.springframework.util.StringUtils#getFilename(String)
	 */
	@Override
	public String getFilename() {
		return StringUtils.getFilename(this.path);
	}

	/**
	 * This implementation returns a description that includes the class path location.
	 */
	@Override
	public String getDescription() {
		StringBuilder builder = new StringBuilder("class path resource [");
		String pathToUse = 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();
	}

	/**
	 * This implementation compares the underlying class path locations.
	 */
	@Override
	public boolean equals(Object obj) {
		if (obj == this) {
			return true;
		}
		if (obj instanceof ClassPathResource) {
			ClassPathResource otherRes = (ClassPathResource) obj;
			return (this.path.equals(otherRes.path) &&
					ObjectUtils.nullSafeEquals(this.classLoader, otherRes.classLoader) &&
					ObjectUtils.nullSafeEquals(this.clazz, otherRes.clazz));
		}
		return false;
	}

	/**
	 * This implementation returns the hash code of the underlying
	 * class path location.
	 */
	@Override
	public int hashCode() {
		return this.path.hashCode();
	}

}

Spring--ClassPathResource的更多相关文章

  1. 深入了解 Java Resource && Spring Resource

    在Java中,为了从相对路径读取文件,经常会使用的方法便是: xxx.class.getResource(); xxx.class.getClassLoader().getResource(); 在S ...

  2. ajax图片上传及FastDFS入门案例.

    今天来开始写图片上传的功能, 现在的图片上传都讲求 上传完成后立刻回显且页面不刷新, 这里到底是怎么做的呢? 当然是借助于ajax了, 但是ajax又不能提交表单, 这里我们还要借助一个插件: jqu ...

  3. JdbcTemplate源码解析

    先写一个测试代码 package jdbc; import java.sql.ResultSet; import java.sql.SQLException; import java.util.Arr ...

  4. Spring之ClassPathResource加载资源文件

    先看Demo: 1 @Test 2 public void testClassPathResource() throws IOException { 3 Resource res = new Clas ...

  5. 8 -- 深入使用Spring -- 3...1 Resource实现类ClassPathResource

    8.3.1 Resource实现类------ClassPathResource : 访问类加载路径下的资源的实现类 2.访问类加载路径下的资源 ClassPathResource 用来访问类加载路径 ...

  6. 学习AOP之透过Spring的Ioc理解Advisor

    花了几天时间来学习Spring,突然明白一个问题,就是看书不能让人理解Spring,一方面要结合使用场景,另一方面要阅读源代码,这种方式理解起来事半功倍.那看书有什么用呢?主要还是扩展视野,毕竟书是别 ...

  7. 【初探Spring】------Spring IOC(三):初始化过程---Resource定位

    我们知道Spring的IoC起到了一个容器的作用,其中装得都是各种各样的Bean.同时在我们刚刚开始学习Spring的时候都是通过xml文件来定义Bean,Spring会某种方式加载这些xml文件,然 ...

  8. 【初探Spring】------Spring IOC(二):初始化过程---简介

    首先我们先来看看如下一段代码 ClassPathResource resource = new ClassPathResource("bean.xml"); DefaultList ...

  9. 【初探Spring】------Spring IOC(一)

    IOC:Inversion of Control(控制反转).IOC它所体现的并不是一种技术,而是一种思想,一种将设计好的对象交给容器来管理的思想.IOC的核心思想就体现在控制.反转这两个词上面,要理 ...

  10. spring笔记5 spring IOC的基础知识1

    1,ioc的概念 Inverse of control ,控制反转,实际的意义是调用类对接口实现类的依赖,反转给第三方的容器管理,从而实现松散耦合: ioc的实现方式有三种,属性注入,构造函数注入,接 ...

随机推荐

  1. Java异常处理-----Throwable类

    Throwable类 1.toString() 输出该异常的类名. 2.getMessage() 输出异常的信息,需要通过构造方法传入异常信息(例如病态信息). 3.printStackTrace() ...

  2. 值集&快速编码(Lookup_code)

    --值集 SELECT ffv.flex_value, ffv.description   FROM fnd_flex_values_vl ffv, fnd_flex_value_sets ffs   ...

  3. SQL Server 索引维护(1)——系统常见的索引问题

    前言: 在很多系统中,比如本人目前管理的数据库,索引经常被滥用,甚至使用DTA(数据库引擎优化顾问)来成批创建索引(DTA目前个人认为它的真正用处应该是在发现缺失的统计信息,在以前的项目中,用过一次D ...

  4. android自定义view实现progressbar的效果

    一键清理是很多Launcher都会带有的功能,其效果也比较美观.实现方式也许有很多中,其中常见的是使用图片drawable来完成的,具体可以参考这篇文章:模仿实现360桌面水晶球式的一键清理特效.本文 ...

  5. 发现----Android Demo

    时间悄悄的走,转眼来实习已经三个月了,三个月的时间,小编慢慢的成长着,从刚开始的电商项目到现在的车段子项目,小编在走过一个又一个项目的同时,走过了一个又一个战胜自己的奇迹,每次遇到一个新的技术点,小编 ...

  6. Linux内核线程

    内核线程是直接由内核本身启动的进程.内核线程实际上是将内核函数委托给独立的进程,与系统中其他进程"并行"执行(实际上,也并行于内核自身的执行),内核线程经常被称为内核"守 ...

  7. android 特卖列表倒计时卡顿问题

    在Android的开发中,我们经常遇见倒计时的操作,通常使用Timer和Handler共同操作来完成.当然也可以使用Android系统控件CountDownTimer,这里我们封装成一个控件,也方便大 ...

  8. Hibernate 缓存机制全面讲解

    简介 为了降低应用程序访问我们的数据的时候的频率,提高数据读取的速率.比如计算机中为了缓解CPU和内存之间速度差异而引入的缓存是一样的道理.Hibernate同样对缓存进行了支持,使得程序的运行效率得 ...

  9. UIActionSheet,UIAlertView技术分享

    UIActionSheet #import "FirstViewController.h" @interface FirstViewController ()<UIActio ...

  10. java单链表常用操作

    总结提高,与君共勉 概述. 数据结构与算法亘古不变的主题,链表也是面试常考的问题,特别是手写代码常常出现,将从以下方面做个小结 [链表个数] [反转链表-循环] [反转链表-递归] [查找链表倒数第K ...