classloader.getresources() 介绍
◆普通情况下,我们都使用相对路径来获取资源,这种灵活性比較大.
比方当前类为com/bbebfe/Test.class
而图像资源比方sample.gif应该放置在com/bbebfe/sample.gif
而假设这些图像资源放置在icons文件夹下,则应该是com/bbebfe/icons/sample.gif
通过当前类文件的路径获取资源主要有例如以下几种方式:
· 如果当前类为com.bbebfe.Test
· 包所在的目录为bin
String
imageName =
"icons/sample.gif"
1, 通过Class.getResource()定位类路径下的资源(bin/com/bbebfe/icons/sample.gif)
Class clazz = this.getClass();
URL url = clazz.getResource(imageName);
2,通过ClassLoader.getResource()定位包的根文件夹下的资源(bin/icons/sample.gif)
Class clazz =
this.getClass();
URLClassLoader
loader = (URLClassLoader)clazz.getClassLoader();
URL url =
loader.getResource(imageName);
3, 通过ClassLoader.findResource()提供自己定制的方式定位资源
URL url = loader.findResource(imageName);
◆那么这三种方法有那些差别, 我们应该在何时使用哪种方法呢?
· Class.getResource() 方法
该方法实际通过该Class的Class
Loader的getResource()方法来获得资源, 在调用ClassLoader的getResource()方法之前, Class.getResource()方法会对资源名称做一定的处理,构建一个该资源的绝对名称(absolute name, 大意是:
+假设资源名称以'/'('"u002f') 開始, 则资源的绝对名称是'/'以后的部分.
假设imageName是"/icons/sample.gif", 则在这里会变成"icons/sample.gif"
+否则对于其它情况, 绝对名称将是例如以下形式(给资源名称的前面加上modified_package_name/):
modified_package_name/resource_name (修正的包名称/资源名称)
当中修正的包名称含义是将当前对象所在的包名称中的'.'('"u002e')替换为'/'
假设ClassLoader.getResource()方法返回一个值为null的URL, 则Class.getResource()方法终于会将资源请求交给ClassLoader.getSystemResource(java.lang.String).
· ClassLoader.getResource() 方法
该对资源进行查找, 资源的名称是以'/'分隔的路径, 这种方法首先查找自己的父亲ClassLoader,由自己的父ClassLoader来查找资源(实际上, 假设父亲的父亲不是空, 则父亲仍会向上提交查找请求). 假设自己的父ClassLoader是null, 则查找Java虚拟机中内建的class loader, 并将资源请求提交给它们, 假设这些操作都失败了, 则ClassLoader会调用自己的findResource()方法来查找资源.
· ClassLoader.findResource() 方法
该方法在内部查找指定的资源, 假设你实现了自己的Class Loader,则应该重载这种方法以自己特定的方式来查找类文件和资源.
◆通过以上的总结, 我们能够看到三点.
1, 不管是getResource(), 还是findResource(), 这些方法都仅仅是资源的定位方法, 终于都仅仅是返回一个URL, 仅仅是对资源的定位而已, 我们随后应通过自己的方法来读取这些资源. 而在Class和ClassLoader中还定义的有getResourceAsStream方法, 该方法是getResource的增强版, 这里就不介绍了.
2,假设须要以类为相对路径查找资源, 则应该调用Class.getResource()方法, 不要直接调用ClassLoader.getResource()方法. 另外, 除非是你自定义了ClassLoader并重载了findResource方法,否则也不要直接调用ClassLoader.findResource方法, 由于在Class.getResource()方法中会对资源名称作一定的处理, 这在上面介绍了, 以下举个实例:
如果我的当前类在EclipseprojectDatabase下, 类所在的包是com.bbebfe.test, 而icons文件夹放在bin/com/bbebfe/test/文件夹下, 我须要得到icons/sample.gif文件的URL, 则调用this.getClass().getResource()得到的URL是:
file:/E:/MyLife/MyProjects/Eclipse3.2/Database/bin/com/bbebfe/test/icons/disremove.gif
3, 有时候我们希望某个jar库的图像资源在同一个icons下统一管理, 而不是为每一个包以下的Class建一个icons, 也就是说须要以库为相对路径来查找资源, 此时则应该调用ClassLoader.getResource()方法, 举个样例:
·某个project有例如以下的包结构:
com.bbebfe.ui
com.bbebfe.test
com.bbebfe.database
·假设以类为相对路径, 则在每一个包下都必须建立一个icons文件夹, 并放置对应的资源文件. 例如以下:
com.bbebfe.ui/icons/...
com.bbebfe.test/icons/...
com.bbebfe.database/icons/...
·而我们可能希望在根文件夹下放置一个icons文件夹, 把全部资源放置在这里管理, 这样还能够防止资源的反复. 就是例如以下形式
com.bbebfe.ui
com.bbebfe.test
com.bbebfe.database
icons/sample.gif ...
则此时我们应该调用ClassLoader.getResource方法, 因为它没有对资源名称作处理, 也就是说没有将修正的包名加入到资源名称前, 所以它会在类所在的包的根下去查找资源.(执行java程序的语法是java
com.bbebfe.ui.Test, 所以根文件夹是com文件夹的上级文件夹).
◆最后, 在Java中对资源进行定位的方法有非常多种, 在Eclipse源码中还有例如以下一段定位文件资源的代码, 还没有时间研究, 以后再谈:
ProtectionDomain domain = Main.class.getProtectionDomain();
CodeSource source = null;
URL result = null;
if (domain != null)
source = domain.getCodeSource();//获得code source
if (source != null)
result = source.getLocation();//获得URL
String path = decode(result.getFile());//
// normalize to not have leading / so we can
check the form
File file = new File(path);
path = file.toString().replace('""',
'/');
// create a file URL (via File) to normalize the
form (e.g., put
// the leading / on if necessary)
path = new File(path).toURL().getFile();
刚才试了一下,发现假设类路径上有反复的资源,getResource()方法会返回类路径上碰到的第一个资源。
而getResources()则会返回当前类载入器路径上的全部反复资源以及父类载入器上的全部反复资源。
比方,在tomcat/lib文件夹下放置一个zip文件,包括config/aaa.txt文件,
在WEB-INF/lib文件夹下复制一份这个zip文件,
再在src文件夹下放上config/aaa.txt文件,
getResource("config/aaa.txt")返回结果是:
file:/D:/eclipse/workspace/demo/WebContent/WEB-INF/classes/config/aaa.txt
getResources("config/aaa.txt")返回结果是:
file:/D:/eclipse/workspace/demo/WebContent/WEB-INF/classes/config/aaa.txt
jar:file:/D:/apache-tomcat-6.0.16/lib/aaaaa.jar!/config/aaa.txt
jar:file:/D:/eclipse/workspace/demo/WebContent/WEB-INF/lib/bbbbb.jar!/config/aaa.txt
classloader.getresources() 介绍的更多相关文章
- Tomcat ClassLoader机制介绍
本文旨在介绍JVM的类加载机制:同时分析Tomcat不能采用默认的加载机制的原因,并对其加载机制做了介绍. 1.JVM中的类加载机制 在Java2之后的版本中,类的加载采用的是一种称为双亲委派的代理模 ...
- ClassLoader简单介绍
要理解ClassLoader,我们可以通过what.how两个方面来解释 一.what:什么事ClassLoader? 1.ClassLoader可以是将class文件加载到JVM方法区. 2.Cla ...
- Class.getResources()和classLoader.getResources()区别
Class.getResource(String path) path不以’/'开头时,默认是从此类所在的包下取资源: path 以’/'开头时,则是从ClassPath根下获取: package t ...
- [认知]ClassLoader 认知一二三
曾经深入了解过ClassLoader,但一直没有时间去总结,现在以参考+自我认识的方式总结一下ClassLoader的相关内容,不能保证100%全,但目前对于一个毛头孩子来说,enough! 首先就要 ...
- ClassLoader
1.双亲委派制 ClassLoadder是一个abstract类 static class sun.misc.Launcher$ExtClassLoader extends java.net.URLC ...
- 深入浅出 JVM ClassLoader
# 前言 在 JVM 综述里面,我们说,JVM 做了三件事情,Java 程序的内存管理, Java Class 二进制字节流的加载(ClassLoader),Java 程序的执行(执行引擎).我们也说 ...
- android classloader双亲托付模式
概述 ClassLoader的双亲托付模式:classloader 按级别分为三个级别:最上级 : bootstrap classLoader(根类载入器) : 中间级:extension class ...
- classloader 学习
classloader就是把类文件加载到jvm中供虚拟机使用,先看一个magic小例子: 首先,我定义一个alex/vicky包,然后在这个包内定义一个接口: public interfaceISer ...
- 深入Spring Boot:ClassLoader的继承关系和影响
前言 对spring boot本身启动原理的分析, Spring boot里的ClassLoader继承关系 可以运行下面提供的demo,分别在不同的场景下运行,可以知道不同场景下的Spring bo ...
随机推荐
- [CSS] :not Selector
The CSS :not() selector allows us to exclude a subset of elements matched by our selector. In this e ...
- 原生 javascript 学习之 js变量
1.变量的命名 方法的命名(驼峰命名法) 全部小写 : 单词与单词之间全部下划线 (my_namespace) 大小写混合 : 第一个单词首字母小写其他单词首字母大写. 规则 首字符 英文字母或下划线 ...
- 未能的导入项目,请确认<Import>声明中的路径正确
对于这样的错误,根据提示应该是项目的管理文件(.csproj)中有问题.找到对应的位置修改即可
- (转)一小时搞定DIV+CSS布局-固定页面开度布局
本文讲解使用DIV+CSS布局最基本的内容,读完本文你讲会使用DIV+CSS进行简单的页面布局. 转载请标明:http://www.kwstu.com/ArticleView/divcss_20139 ...
- tomcat免安装版注册为系统服务
环境: OS:windows7_64bit JDK:jdk1.6_64bit tomcat:apache-tomcat-7.0.61-windows-x64 1.修改tomcat/bin/servic ...
- MFC的初始化过程和消息映射技术
1.删除#include <windows.h>--win32中的-(使用win32工程编程mfc必须删除) 添加#include <afxwin.h> -- mfc中的- 2 ...
- 为什么memset不能将数组元素初始化为1?
原型:extern void *memset(void *buffer, int c, int count); 功能:把buffer所指内存区域的前count个字节设置成字符c. 包含头文件:< ...
- Avro基础
一.Avro的基本功能 1.定义了数据模式文件的语法,一般使用json文件.以及一些数据基本类型与复杂类型. 2.定义了数据序列化到文件后的数据格式,此格式可供各种语言进行读取. 3.为部分语言定义了 ...
- 为Mac自带的Apache配置PHP和虚拟机
操作系统:os x 10.11.2 1.启动apache 打开终端(terminal),输入命令:sudo apachectl -k start ; 在浏览器地址栏中输入:http://localho ...
- 文件:因为懂你,所以永恒 - 零基础入门学习Python028
文件:因为懂你,所以永恒 让编程改变世界 Change the world by program 因为懂你,所以永恒 大多数的程序都遵循着:输入->处理->输出的模型,首先接受输入数据,然 ...