/*
 * 用一个给定的类加载器或者给定的类来加载资源
 */
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. Maven仓库概述

    什么是Maven仓库 在Maven世界中,任何一个依赖.插件或项目构建的输出,都可以称为构建.由于Maven引入了坐标机制,任何一个构建都可以由其坐标唯一标识.坐标是一个构建在Maven世界中的逻辑表 ...

  2. Dynamics CRM The difference between UserId and InitiatingUserId in Plugin

    对于这两者的不同,MSDN的解释如下 • IExecutionContext.UserId Property: Gets the global unique identifier of the sys ...

  3. 开源控件ViewPagerIndicator的使用

    此文转载自http://www.jianshu.com/p/a2263ee3e7c3 前几天学习了ViewPager作为引导页和Tab的使用方法.后来也有根据不同的使用情况改用Fragment作为Ta ...

  4. Android简易实战教程--第二十一话《内容观察者监听数据库变化》

    当数据库的数据发生改变,我们又想知道具体改变的情况时,就需要对数据库的变化情况做一个监控.这个任务,就由内容观察者来完成.下面这个案例,为短信数据库注册内容观察者,来监控短信的变化情况,当短信数据库发 ...

  5. Xcode一种涉及到多桌面的调试技巧

    大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请多提意见,如果觉得不错请多多支持点赞.谢谢! hopy ;) Mac本身是支持多桌面功能的,以下是本猫OS界面的截图: 可以 ...

  6. Python读取JSON数据,并解决字符集不匹配问题

    今天来谈一谈Python解析JSON数据,并写入到本地文件的一个小例子. – 思路如下 从一个返回JSON天气数据的网站获取到目标JSON数据串 使用Python解析出需要的部分 写入到本地文件,供其 ...

  7. 关于weak

    #define DECLARE_WEAK_SELF __typeof(&*self) __weak weakSelf = self #define DECLARE_STRONG_SELF __ ...

  8. API创建/更新员工联系电话

    DECLARE ln_phone_id PER_PHONES.PHONE_ID%TYPE; ln_object_version_number PER_PHONES.OBJECT_VERSION_NUM ...

  9. 06 Activity隐式跳转

    一,隐式跳转 某个Activity 需要在清单文件配置某个Activity如下信息: 注意:category要和action一起用 action:制定一个活动 在隐式跳转的可以用到 category ...

  10. Android的ImageView介绍-android学习之旅(二十二)

    ImageView简介 imageView继承于View,主要用于显示图片,凡是Drawable对象都可以用它显示. ImageView直接派生了ImageButton和ZoomButton等组件. ...