通过class的getResource方法,查找与给定类相关的资源。
1、class中getResource在JDK中的定义
Finds a resource with a given name. The rules for searching resources associated with a given class are implemented by the definingclass loader of the class. This method delegates to this object's class loader. If this object was loaded by the bootstrap class loader, the method delegates to
Before delegation, an absolute resource name is constructed from the given resource name using this algorithm:
If the name begins with a '/' ('\u002f'), then the absolute name of the resource is the portion of thename following the '/'.
Otherwise, the absolute name is of the following form:
modified_package_name/name
Where the modified_package_name is the package name of this object with'/' substituted for '.' ('\u002e').
Parameters:
name name of the desired resource
Returns:
A
null if no resource with this name is found
Since:
JDK1.1
getResource public URL getResource(String name)
查找带有给定名称的资源。查找与给定类相关的资源的规则是通过定义类的
class loader 实现的。此方法委托给此对象的类加载器。如果此对象通过引导类加载器加载,则此方法将委托给
ClassLoader.getSystemResource(java.lang.String)。
在委托前,使用下面的算法从给定的资源名构造一个绝对资源名:
如果 name 以 '/' ('\u002f') 开始,则绝对资源名是 '/' 后面的name 的一部分。
否则,绝对名具有以下形式:
modified_package_name/name
其中 modified_package_name 是此对象的包名,该名用 '/' 取代了 '.' ('\u002e')。
参数:
name - 所需资源的名称
返回:
一个
URL 对象;如果找不到带有该名称的资源,则返回
null
从以下版本开始:
JDK1.1
getResource方法的实现如下
//getResource
public java.net.URL getResource(String name) {
name = resolveName(name);
ClassLoader cl = getClassLoader0();
if (cl==null) {
// A system class.
return ClassLoader.getSystemResource(name);
}
return cl.getResource(name);
}
//resolveName
private String resolveName(String name) {
if (name == null) {
return name;
}
if (!name.startsWith("/")) {
Class c = this;
while (c.isArray()) {
c = c.getComponentType();
}
String baseName = c.getName();
int index = baseName.lastIndexOf('.');
if (index != -1) {
name = baseName.substring(0, index).replace('.', '/')
+"/"+name;
}
} else {
name = name.substring(1);
}
return name;
}
2、classloader中的getResource在JDK中的定义
Finds the resource with the given name. A resource is some data (images, audio, text, etc) that can be accessed by class code in a way that is independent of the location of the code.
The name of a resource is a '/'-separated path name that identifies the resource.
This method will first search the parent class loader for the resource; if the parent isnull the path of the class loader built-in to the virtual machine is searched. That failing, this method will invoke
Parameters:
name The resource name
Returns:
A
URL object for reading the resource, or
null if the resource could not be found or the invoker doesn't have adequate privileges to get the resource.
Since:
1.1
getResource public URL getResource(String name)
查找具有给定名称的资源。资源是可以通过类代码以与代码基无关的方式访问的一些数据(图像、声音、文本等)。
资源名称是以 '/' 分隔的标识资源的路径名称。
此方法首先搜索资源的父类加载器;如果父类加载器为 null,则搜索的路径就是虚拟机的内置类加载器的路径。如果搜索失败,则此方法将调用 findResource(String) 来查找资源。
参数:
name - 资源名称
返回:
读取资源的
URL 对象;如果找不到该资源,或者调用者没有足够的权限获取该资源,则返回
null。
从以下版本开始:
1.1
getResource方法的实现如下
//getResource
public URL getResource(String name) {
URL url;
if (parent != null) {
url = parent.getResource(name);
} else {
url = getBootstrapResource(name);
}
if (url == null) {
url = findResource(name);
}
return url;
}
/**
* Find resources from the VM's built-in classloader.
*/
private static URL getBootstrapResource(String name) {
try {
// If this is a known JRE resource, ensure that its bundle is
// downloaded. If it isn't known, we just ignore the download
// failure and check to see if we can find the resource anyway
// (which is possible if the boot class path has been modified).
sun.jkernel.DownloadManager.getBootClassPathEntryForResource(name);
} catch (NoClassDefFoundError e) {
// This happens while Java itself is being compiled; DownloadManager
// isn't accessible when this code is first invoked. It isn't an
// issue, as if we can't find DownloadManager, we can safely assume
// that additional code is not available for download.
}
URLClassPath ucp = getBootstrapClassPath();
Resource res = ucp.getResource(name);
return res != null ? res.getURL() : null;
}
/**
* Finds the resource with the given name. Class loader implementations
* should override this method to specify where to find resources.
*
* @param name
* The resource name
*
* @return A URL object for reading the resource, or
* null if the resource could not be found
*
* @since 1.2
*/
protected URL findResource(String name) {
return null;
}
3、总结
获取资源是,推荐使用class的getResource方法,它实质上是调用的classloader的getResource方法。
class的getResource方法,对name的路径做了一下解析,
所以,自己没有必要调用classloader的getResource方法(因为它的参数name是有规则要求的,但是在API中没有体现。从类路径下搜索,不能以"/"开头)。
例如:
package org.wsr.spring.demo;
public class Demo {
public static void main(String[] args) throws Exception {
String path = new Demo().getClass().getClassLoader().getResource("").getPath();
System.out.println(path);
path = new Demo().getClass().getResource("").getPath();
System.out.println(path);
path = Demo.class.getResource("text.txt").getPath();
System.out.println(path);
}
}
// output
// /D:/WorkSpace/e_my_work/beantest/target/classes/
// /D:/WorkSpace/e_my_work/beantest/target/classes/org/wsr/spring/demo/
// /D:/WorkSpace/e_my_work/beantest/target/classes/org/wsr/spring/demo/text.txt