Spring源码之Resource加载源码解析(三)
来源:互联网 发布:哈登什么水平知乎 编辑:程序博客网 时间:2024/05/20 09:21
ResourceLoader 架构概览
ResourceLoader接口用于返回Resource对象;其实现可以看作是一个生产Resource的工厂类。
可以分为两类:
第一类:默认资源加载器DefaultResourceLoader及其子类;
Spring提供了一个适用于所有环境的DefaultResourceLoader实现,可以返回ClassPathResource、UrlResource;还提供一个用于web环境的ServletContextResourceLoader,它继承了DefaultResourceLoader的所有功能,又额外提供了获取ServletContextResource的支持。
第二类: 应用上下文ApplicationContext接口及其实现类;
ApplicationContext的主要实现类ClassPathXmlApplicationContext和FileSystemXmlApplicationContext,前者默认从类路径加载配置文件,后者默认从文件系统中装载配置文件。本次不做说明,后面会单独介绍ApplicationContext。
ResourceLoader接口源码解析
//通过ResourceLoader获取资源public interface ResourceLoader { //加载的类路径伪URL前缀:“classpath:” String CLASSPATH_URL_PREFIX = ResourceUtils.CLASSPATH_URL_PREFIX; //根据提供的location参数返回相应的Resource对象 Resource getResource(String location); //返回加载这些Resource的ClassLoader ClassLoader getClassLoader();}
ResourceLoader在进行加载资源时需要使用前缀来指定需要加载:“classpath:path”表示返回ClasspathResource,“http://path”和“file:path”表示返回UrlResource资源,如果不加前缀则需要根据当前上下文来决定,DefaultResourceLoader默认实现可以加载classpath资源
DefaultResourceLoader及其子类源码解析
public class DefaultResourceLoader implements ResourceLoader { //加载该资源类加载器 private ClassLoader classLoader; //构造函数 public DefaultResourceLoader() { //默认:实际资源访问时使用的线程上下文类加载器 this.classLoader = ClassUtils.getDefaultClassLoader(); } //构造函数 public DefaultResourceLoader(ClassLoader classLoader) { this.classLoader = classLoader; } //设置类加载器 public void setClassLoader(ClassLoader classLoader) { this.classLoader = classLoader; } //获取类加载器,未设置,则返回实际资源访问时使用的线程上下文类加载器 public ClassLoader getClassLoader() { return (this.classLoader != null ? this.classLoader : ClassUtils.getDefaultClassLoader()); } //根据提供的location参数返回相应的资源句柄Resource。 public Resource getResource(String location) { Assert.notNull(location, "Location must not be null"); //“classpath:”前缀,返回ClassPathResource对象 if (location.startsWith(CLASSPATH_URL_PREFIX)) { return new ClassPathResource(location.substring(CLASSPATH_URL_PREFIX.length()), getClassLoader()); } else { try { // Try to parse the location as a URL... //尝试将location转化为URL,再返回UrlResource对象 URL url = new URL(location); return new UrlResource(url); } catch (MalformedURLException ex) { //不是URL,则解析为资源路径。 return getResourceByPath(location); } } } //返回给定路径path上资源的资源句柄Resource。 protected Resource getResourceByPath(String path) { //默认实现支持类路径位置 return new ClassPathContextResource(path, getClassLoader()); } //类加载路径下的资源 private static class ClassPathContextResource extends ClassPathResource implements ContextResource { public ClassPathContextResource(String path, ClassLoader classLoader) { super(path, classLoader); } public String getPathWithinContext() { return getPath(); } // 关键 -> 创建相相对于当前资源路径下的资源。 // 假设当前的 file 路径为 D:/DEMO/HELLO.TXT,且 relativePath = GOOD.TXT // 则该方法创建的资源路径为 D:/DEMO/GOOD.TXT @Override public Resource createRelative(String relativePath) { String pathToUse = StringUtils.applyRelativePath(getPath(), relativePath); return new ClassPathContextResource(pathToUse, getClassLoader()); } }}//servlet上下文资源加载器public class ServletContextResourceLoader extends DefaultResourceLoader { private final ServletContext servletContext; //构造函数 public ServletContextResourceLoader(ServletContext servletContext) { this.servletContext = servletContext; } //此实现支持Web应用程序根目录下的文件路径。 @Override protected Resource getResourceByPath(String path) { return new ServletContextResource(this.servletContext, path); }}//文件系统资源加载器public class FileSystemResourceLoader extends DefaultResourceLoader { //将资源路径解析为文件系统路径。 @Override protected Resource getResourceByPath(String path) { if (path != null && path.startsWith("/")) { path = path.substring(1); } return new FileSystemContextResource(path); } //文件系统里面的资源 private static class FileSystemContextResource extends FileSystemResource implements ContextResource { public FileSystemContextResource(String path) { super(path); } public String getPathWithinContext() { return getPath(); } }}//类相关资源加载器public class ClassRelativeResourceLoader extends DefaultResourceLoader { private final Class clazz; //创建一个指定类的相关资源加载器 public ClassRelativeResourceLoader(Class clazz) { Assert.notNull(clazz, "Class must not be null"); this.clazz = clazz; setClassLoader(clazz.getClassLoader()); } protected Resource getResourceByPath(String path) { return new ClassRelativeContextResource(path, this.clazz); } //获取类路径下的资源文件 private static class ClassRelativeContextResource extends ClassPathResource implements ContextResource { private final Class clazz; public ClassRelativeContextResource(String path, Class clazz) { super(path, clazz); this.clazz = clazz; } public String getPathWithinContext() { return getPath(); } @Override public Resource createRelative(String relativePath) { String pathToUse = StringUtils.applyRelativePath(getPath(), relativePath); return new ClassRelativeContextResource(pathToUse, this.clazz); } }}
阅读全文
0 0
- Spring源码之Resource加载源码解析(三)
- Spring源码之Resource加载源码解析(一)
- Spring源码之Resource加载源码解析(二)
- spring源码解析-资源管理Resource
- Spring源码解析之Bean的加载
- Spring源码之ApplicationContext(三)加载BeanFactory
- Spring 源码解析之HandlerAdapter源码解析(三)
- Spring 源码解析之HandlerAdapter源码解析(三)
- Spring 源码解析之HandlerAdapter源码解析(三)
- Spring源码解析之-资源加载(1)
- spring IoC源码分析 (3)Resource解析
- Spring Bean加载源码解析
- Spring源码解析之-Aop源码解析(2)
- 深入Spring IOC源码之Resource
- Spring源码阅读之Resource接口
- 深入Spring IOC源码之Resource
- spring resource源码讲解
- (三)Mina源码解析之IoFilter
- java多位排序
- 2017.7.13 流水帐系列
- JS编程训练 | 题10:计数
- java.io(基本操作方式)
- docker之namespace编
- Spring源码之Resource加载源码解析(三)
- 1、Linux命令
- 一、Dreamweaver 8安装
- Python学习笔记之遍历目录文件(递归和walk())
- mysql 5.6之 增量备份(1):log-bin启动
- 60天高效通过软考高级实战复习攻略(干货)
- Java toString 方法
- dos命令之 assoc 用法详解
- 【HTML5学习笔记】22:CSS盒模型 下