/*
* Copyright (c) 2002-2012 Alibaba Group Holding Limited.
* All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.citrus.util;
import static com.alibaba.citrus.util.CollectionUtil.*;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import com.alibaba.citrus.util.io.StreamUtil;
/**
* <p>
* 查找并装入类和资源的辅助类。
* </p>
* <p>
* <code>ClassLoaderUtil</code>查找类和资源的效果, 相当于<code>ClassLoader.loadClass</code>
* 方法和<code>ClassLoader.getResource</code>方法。 但<code>ClassLoaderUtil</code>
* 总是首先尝试从<code>Thread.getContextClassLoader()</code>方法取得
* <code>ClassLoader</code>中并装入类和资源。 这种方法避免了在多级<code>ClassLoader</code>
* 的情况下,找不到类或资源的情况。
* </p>
* <p>
* 假设有如下情况:
* </p>
* <ul>
* <li>工具类<code>A</code>是从系统<code>ClassLoader</code>装入的(classpath)</li>
* <li>类<code>B</code>是Web Application中的一个类,是由servlet引擎的<code>ClassLoader</code>
* 动态装入的</li>
* <li>资源文件<code>C.properties</code>也在Web Application中,只有servlet引擎的动态
* <code>ClassLoader</code>可以找到它</li>
* <li>类<code>B</code>调用工具类<code>A</code>的方法,希望通过类<code>A</code>取得资源文件
* <code>C.properties</code></li>
* </ul>
* <p>
* 如果类<code>A</code>使用
* <code>getClass().getClassLoader().getResource("C.properties")</code>
* , 就会失败,因为系统<code>ClassLoader</code>不能找到此资源。
* 但类A可以使用ClassLoaderUtil.getResource("C.properties"),就可以找到这个资源,
* 因为ClassLoaderUtil调用<code>Thread.currentThead().getContextClassLoader()</code>
* 取得了servlet引擎的<code>ClassLoader</code>, 从而找到了这个资源文件。
* </p>
*
* @author Michael Zhou
*/
public class ClassLoaderUtil {
// ==========================================================================
// 取得context class loader的方法。
// ==========================================================================
/**
* 取得当前线程的<code>ClassLoader</code>。这个功能需要JDK1.2或更高版本的JDK的支持。
*
* @return 当前线程的<code>ClassLoader</code>
*/
public static ClassLoader getContextClassLoader() {
return Thread.currentThread().getContextClassLoader();
}
// ==========================================================================
// 装入类的方法。
// ==========================================================================
/**
* 从当前线程的<code>ClassLoader</code>装入类。对于JDK1.2以下,则相当于
* <code>Class.forName</code>。
*
* @param className 要装入的类名
* @return 已装入的类
* @throws ClassNotFoundException 如果类没找到
*/
public static Class<?> loadClass(String className) throws ClassNotFoundException {
return loadClass(className, getContextClassLoader());
}
/**
* 从指定的调用者的<code>ClassLoader</code>装入类。
*
* @param className 要装入的类名
* @param referrer 调用者类,如果为<code>null</code>,则该方法相当于
* <code>Class.forName</code>
* @return 已装入的类
* @throws ClassNotFoundException 如果类没找到
*/
public static Class<?> loadClass(String className, Class<?> referrer) throws ClassNotFoundException {
ClassLoader classLoader = getReferrerClassLoader(referrer);
// 如果classLoader为null,表示从ClassLoaderUtil所在的classloader中装载,
// 这个classloader未必是System class loader。
return loadClass(className, classLoader);
}
/**
* 从指定的<code>ClassLoader</code>中装入类。如果未指定<code>ClassLoader</code>, 则从装载
* <code>ClassLoaderUtil</code>的<code>ClassLoader</code>中装入。
*
* @param className 要装入的类名
* @param classLoader 从指定的<code>ClassLoader</code>中装入类,如果为<code>null</code>
* ,表示从<code>ClassLoaderUtil</code>所在的class loader中装载
* @return 已装入的类
* @throws ClassNotFoundException 如果类没找到
*/
public static Class<?> loadClass(String className, ClassLoader classLoader) throws ClassNotFoundException {
if (className == null) {
return null;
}
if (classLoader == null) {
return Class.forName(className);
} else {
return Class.forName(className, true, classLoader);
}
}
/**
* 按照标准的jar service规范搜索并装载指定名称的service类。
* <p>
* 搜索方法是在class loader中查找<code>META-INF/services/serviceId</code>
* 文件,并将其内容作为service类名。
* </p>
*
* @param serviceId 服务名
* @return service class
* @throws ClassNotFoundException 如果service class找不到,或装载service文件失败
*/
public static Class<?> loadServiceClass(String serviceId) throws ClassNotFoundException {
return loadServiceClass(serviceId, getContextClassLoader());
}
/**
* 按照标准的jar service规范搜索并装载指定名称的service类。
* <p>
* 搜索方法是在class loader中查找<code>META-INF/services/serviceId</code>
* 文件,并将其内容作为service类名。
* </p>
*
* @param serviceId 服务名
* @param referrer 调用者类,如果为<code>null</code>,表示在<code>ClassLoaderUtil</code>
* 的class loader中找。
* @return service class
* @throws ClassNotFoundException 如果service class找不到,或装载service文件失败
*/
public static Class<?> loadServiceClass(String serviceId, Class<?> referrer) throws ClassNotFoundException {
ClassLoader classLoader = getReferrerClassLoader(referrer);
// 如果classLoader为null,表示从ClassLoaderUtil所在的classloader中查找,
return loadServiceClass(serviceId, classLoader);
}
/**
* 按照标准的jar service规范搜索并装载指定名称的service类。
* <p>
* 搜索方法是在class loader中查找<code>META-INF/services/serviceId</code>
* 文件,并将其内容作为service类名。
* </p>
*
* @param serviceId 服务名
* @param classLoader 在指定classLoader中查找,如果为<code>null</code>,表示在
* <code>ClassLoaderUtil</code>的class loader中找。
* @return service class
* @throws ClassNotFoundException 如果service class找不到,或装载service文件失败
*/
public static Class<?> loadServiceClass(String serviceId, ClassLoader classLoader) throws ClassNotFoundException {
if (serviceId == null) {
return null;
}
serviceId = "META-INF/services/" + serviceId;
InputStream istream = getResourceAsStream(serviceId, classLoader);
if (istream == null) {
throw new ServiceNotFoundException("Could not find " + serviceId);
}
// 读文件/META-INF/services/serviceId。
String serviceClassName;
try {
serviceClassName = StringUtil.trimToEmpty(StreamUtil.readText(istream, "UTF-8", true));
} catch (IOException e) {
throw new ServiceNotFoundException("Failed to load " + serviceId, e);
}
return ClassLoaderUtil.loadClass(serviceClassName, classLoader);
}
/**
* 首先试图装入指定名称的类,如果找不到,再按照标准的jar service规范搜索并装载指定名称的service类。
* <p>
* 搜索service的方法是在class loader中查找<code>META-INF/services/serviceId</code>
* 文件,并将其内容作为service类名。
* </p>
*
* @param className 要装入的类名
* @param serviceId 服务名
* @return service class
* @throws ClassNotFoundException 如果service class找不到,或装载service文件失败
*/
public static Class<?> loadServiceClass(String className, String serviceId) throws ClassNotFoundException {
return loadServiceClass(className, serviceId, getContextClassLoader());
}
/**
* 首先试图装入指定名称的类,如果找不到,再按照标准的jar service规范搜索并装载指定名称的service类。
* <p>
* 搜索service的方法是在class loader中查找<code>META-INF/services/serviceId</code>
* 文件,并将其内容作为service类名。
* </p>
*
* @param className 要装入的类名
* @param serviceId 服务名
* @param referrer 调用者类,如果为<code>null</code>,表示在<code>ClassLoaderUtil</code>
* 的class loader中找。
* @return service class
* @throws ClassNotFoundException 如果service class找不到,或装载service文件失败
*/
public static Class<?> loadServiceClass(String className, String serviceId, Class<?> referrer)
throws ClassNotFoundException {
ClassLoader classLoader = getReferrerClassLoader(referrer);
// 如果classLoader为null,表示从ClassLoaderUtil所在的classloader中查找,
return loadServiceClass(className, serviceId, classLoader);
}
/**
* 首先试图装入指定名称的类,如果找不到,再按照标准的jar service规范搜索并装载指定名称的service类。
* <p>
* 搜索service的方法是在class loader中查找<code>META-INF/services/serviceId</code>
* 文件,并将其内容作为service类名。
* </p>
*
* @param className 要装入的类名
* @param serviceId 服务名
* @param classLoader 在指定classLoader中查找,如果为<code>null</code>,表示在
* <code>ClassLoaderUtil</code>的class loader中找。
* @return service class
* @throws ClassNotFoundException 如果service class找不到,或装载service文件失败
*/
public static Class<?> loadServiceClass(String className, String serviceId, ClassLoader classLoader)
throws ClassNotFoundException {
try {
// 先尝试装入class。
if (className != null) {
return loadClass(className, classLoader);
}
} catch (ClassNotFoundException e) {
}
// 找不到,尝试查找service。
return loadServiceClass(serviceId, classLoader);
}
/**
* 取得调用者的class loader。
*
* @param referrer 调用者类
* @return 调用者的class loader,如果referrer为<code>null</code>,则返回
* <code>null</code>
*/
private static ClassLoader getReferrerClassLoader(Class<?> referrer) {
ClassLoader classLoader = null;
if (referrer != null) {
classLoader = referrer.getClassLoader();
// classLoader为null,说明referrer类是由bootstrap classloader装载的,
// 例如:java.lang.String
if (classLoader == null) {
classLoader = ClassLoader.getSystemClassLoader();
}
}
return classLoader;
}
// ==========================================================================
// 装入并实例化类的方法。
// ==========================================================================
/**
* 从当前线程的<code>ClassLoader</code>装入类并实例化之。
*
* @param className 要实例化的类名
* @return 指定类名的实例
* @throws ClassNotFoundException 如果类没找到
* @throws ClassInstantiationException 如果实例化失败
*/
public static Object newInstance(String className) throws ClassNotFoundException, ClassInstantiationException {
return newInstance(loadClass(className));
}
/**
* 从指定的调用者的<code>ClassLoader</code>装入类并实例化之。
*
* @param className 要实例化的类名
* @param referrer 调用者类,如果为<code>null</code>,则从<code>ClassLoaderUtil</code>
* 所在的class loader装载
* @return 指定类名的实例
* @throws ClassNotFoundException 如果类没找到
* @throws ClassInstantiationException 如果实例化失败
*/
public static Object newInstance(String className, Class<?> referrer) throws ClassNotFoundException,
ClassInstantiationException {
return newInstance(loadClass(className, referrer));
}
/**
* 从指定的<code>ClassLoader</code>中装入类并实例化之。如果未指定<code>ClassLoader</code>, 则从装载
* <code>ClassLoaderUtil</code>的<code>ClassLoader</code>中装入。
*
* @param className 要实例化的类名
* @param classLoader 从指定的<code>ClassLoader</code>中装入类,如果为<code>null</code>
* ,表示从<code>ClassLoaderUtil</code>所在的class loader中装载
* @return 指定类名的实例
* @throws ClassNotFoundException 如果类没找到
* @throws ClassInstantiationException 如果实例化失败
*/
public static Object newInstance(String className, ClassLoader classLoader) throws ClassNotFoundException,
ClassInstantiationException {
return newInstance(loadClass(className, classLoader));
}
/**
* 创建指定类的实例。
*
* @param clazz 要创建实例的类
* @return 指定类的实例
* @throws ClassInstantiationException 如果实例化失败
*/
private static Object newInstance(Class<?> clazz) throws ClassInstantiationException {
if (clazz == null) {
return null;
}
try {
return clazz.newInstance();
} catch (InstantiationException e) {
throw new ClassInstantiationException("Failed to instantiate class: " + clazz.getName(), e);
} catch (IllegalAccessException e) {
throw new ClassInstantiationException("Failed to instantiate class: " + clazz.getName(), e);
} catch (Exception e) {
throw new ClassInstantiationException("Failed to instantiate class: " + clazz.getName(), e);
}
}
/**
* 按照标准的jar service规范搜索并装载指定名称的service类并实例化之。
* <p>
* 搜索service的方法是在class loader中查找<code>META-INF/services/serviceId</code>
* 文件,并将其内容作为service类名。
* </p>
*
* @param serviceId 服务名
* @return 实例类
* @throws ClassNotFoundException 如果service class找不到,或装载service文件失败
* @throws ClassInstantiationException 如果实例化失败
*/
public static Object newServiceInstance(String serviceId) throws ClassNotFoundException,
ClassInstantiationException {
return newInstance(loadServiceClass(serviceId));
}
/**
* 按照标准的jar service规范搜索并装载指定名称的service类并实例化之。
* <p>
* 搜索service的方法是在class loader中查找<code>META-INF/services/serviceId</code>
* 文件,并将其内容作为service类名。
* </p>
*
* @param serviceId 服务名
* @param referrer 调用者类,如果为<code>null</code>,表示在<code>ClassLoaderUtil</code>
* 的class loader中找。
* @return 实例类
* @throws ClassNotFoundException 如果service class找不到,或装载service文件失败
* @throws ClassInstantiationException 如果实例化失败
*/
public static Object newServiceInstance(String serviceId, Class<?> referrer) throws ClassNotFoundException,
ClassInstantiationException {
return newInstance(loadServiceClass(serviceId, referrer));
}
/**
* 按照标准的jar service规范搜索并装载指定名称的service类并实例化之。
* <p>
* 搜索service的方法是在class loader中查找<code>META-INF/services/serviceId</code>
* 文件,并将其内容作为service类名。
* </p>
*
* @param serviceId 服务名
* @param classLoader 在指定classLoader中查找,如果为<code>null</code>,表示在
* <code>ClassLoaderUtil</code>的class loader中找。
* @return 实例类
* @throws ClassNotFoundException 如果service class找不到,或装载service文件失败
* @throws ClassInstantiationException 如果实例化失败
*/
public static Object newServiceInstance(String serviceId, ClassLoader classLoader) throws ClassNotFoundException,
ClassInstantiationException {
return newInstance(loadServiceClass(serviceId, classLoader));
}
/**
* 首先试图装入指定名称的类,如果找不到,再按照标准的jar service规范搜索并装载指定名称的service类。 找到以后实例化之。
* <p>
* 搜索service的方法是在class loader中查找<code>META-INF/services/serviceId</code>
* 文件,并将其内容作为service类名。
* </p>
*
* @param className 要装入的类名
* @param serviceId 服务名
* @return 实例类
* @throws ClassNotFoundException 如果service class找不到,或装载service文件失败
* @throws ClassInstantiationException 如果实例化失败
*/
public static Object newServiceInstance(String className, String serviceId) throws ClassNotFoundException,
ClassInstantiationException {
return newInstance(loadServiceClass(className, serviceId));
}
/**
* 首先试图装入指定名称的类,如果找不到,再按照标准的jar service规范搜索并装载指定名称的service类。 找到以后实例化之。
* <p>
* 搜索service的方法是在class loader中查找<code>META-INF/services/serviceId</code>
* 文件,并将其内容作为service类名。
* </p>
*
* @param className 要装入的类名
* @param serviceId 服务名
* @param referrer 调用者类,如果为<code>null</code>,表示在<code>ClassLoaderUtil</code>
* 的class loader中找。
* @return 实例类
* @throws ClassNotFoundException 如果service class找不到,或装载service文件失败
* @throws ClassInstantiationException 如果实例化失败
*/
public static Object newServiceInstance(String className, String serviceId, Class<?> referrer)
throws ClassNotFoundException, ClassInstantiationException {
return newInstance(loadServiceClass(className, serviceId, referrer));
}
/**
* 首先试图装入指定名称的类,如果找不到,再按照标准的jar service规范搜索并装载指定名称的service类。 找到以后实例化之。
* <p>
* 搜索service的方法是在class loader中查找<code>META-INF/services/serviceId</code>
* 文件,并将其内容作为service类名。
* </p>
*
* @param className 要装入的类名
* @param serviceId 服务名
* @param classLoader 在指定classLoader中查找,如果为<code>null</code>,表示在
* <code>ClassLoaderUtil</code>的class loader中找。
* @return 实例类
* @throws ClassNotFoundException 如果service class找不到,或装载service文件失败
* @throws ClassInstantiationException 如果实例化失败
*/
public static Object newServiceInstance(String className, String serviceId, ClassLoader classLoader)
throws ClassNotFoundException, ClassInstantiationException {
return newInstance(loadServiceClass(className, serviceId, classLoader));
}
// ==========================================================================
// 装入和查找资源文件的方法。
// ==========================================================================
/**
* 从<code>ClassLoader</code>取得所有resource URL。按如下顺序查找:
* <ol>
* <li>在当前线程的<code>ClassLoader</code>中查找。</li>
* <li>在装入自己的<code>ClassLoader</code>中查找。</li>
* <li>通过<code>ClassLoader.getSystemResource</code>方法查找。</li>
* </ol>
*
* @param resourceName 要查找的资源名,就是以"/"分隔的标识符字符串
* @return resource的URL数组,如果没找到,则返回空数组。数组中保证不包含重复的URL。
*/
public static URL[] getResources(String resourceName) {
List<URL> urls = createLinkedList();
boolean found = false;
// 首先试着从当前线程的ClassLoader中查找。
found = getResources(urls, resourceName, getContextClassLoader(), false);
// 如果没找到,试着从装入自己的ClassLoader中查找。
if (!found) {
found = getResources(urls, resourceName, ClassLoaderUtil.class.getClassLoader(), false);
}
// 最后的尝试: 在系统ClassLoader中查找(JDK1.2以上),
// 或者在JDK的内部ClassLoader中查找(JDK1.2以下)。
if (!found) {
found = getResources(urls, resourceName, null, true);
}
// 返回不重复的列表。
return getDistinctURLs(urls);
}
/**
* 从指定调用者所属的<code>ClassLoader</code>取得所有resource URL。
*
* @param resourceName 要查找的资源名,就是以"/"分隔的标识符字符串
* @param referrer 调用者类,如果为<code>null</code>,表示在<code>ClassLoaderUtil</code>
* 的class loader中找
* @return resource的URL数组,如果没找到,则返回空数组。数组中保证不包含重复的URL。
*/
public static URL[] getResources(String resourceName, Class<?> referrer) {
ClassLoader classLoader = getReferrerClassLoader(referrer);
List<URL> urls = createLinkedList();
getResources(urls, resourceName, classLoader, classLoader == null);
// 返回不重复的列表。
return getDistinctURLs(urls);
}
/**
* 从指定的<code>ClassLoader</code>中取得所有resource URL。如果未指定
* <code>ClassLoader</code>, 则从装载<code>ClassLoaderUtil</code>的
* <code>ClassLoader</code>中取得所有resource URL。
*
* @param resourceName 要查找的资源名,就是以"/"分隔的标识符字符串
* @param classLoader 从指定的<code>ClassLoader</code>中查找
* @return resource的URL数组,如果没找到,则返回空数组。数组中保证不包含重复的URL。
*/
public static URL[] getResources(String resourceName, ClassLoader classLoader) {
List<URL> urls = createLinkedList();
getResources(urls, resourceName, classLoader, classLoader == null);
// 返回不重复的列表。
return getDistinctURLs(urls);
}
/**
* 在指定class loader中查找指定名称的resource,把所有找到的resource的URL放入指定的集合中。
*
* @param urlSet 存放resource URL的集合
* @param resourceName 资源名
* @param classLoader 类装入器
* @param sysClassLoader 是否用system class loader装载资源
* @return 如果找到,则返回<code>true</code>
*/
private static boolean getResources(List<URL> urlSet, String resourceName, ClassLoader classLoader,
boolean sysClassLoader) {
if (resourceName == null) {
return false;
}
Enumeration<URL> i = null;
try {
if (classLoader != null) {
i = classLoader.getResources(resourceName);
} else if (sysClassLoader) {
i = ClassLoader.getSystemResources(resourceName);
}
} catch (IOException e) {
}
if (i != null && i.hasMoreElements()) {
while (i.hasMoreElements()) {
urlSet.add(i.nextElement());
}
return true;
}
return false;
}
/**
* 去除URL列表中的重复项。
*
* @param urls URL列表
* @return 不重复的URL数组,如果urls为<code>null</code>,则返回空数组
*/
private static URL[] getDistinctURLs(List<URL> urls) {
if (urls == null || urls.size() == 0) {
return new URL[0];
}
Set<URL> urlSet = createHashSet();
for (Iterator<URL> i = urls.iterator(); i.hasNext(); ) {
URL url = i.next();
if (urlSet.contains(url)) {
i.remove();
} else {
urlSet.add(url);
}
}
return urls.toArray(new URL[urls.size()]);
}
/**
* <p>
* 从<code>ClassLoader</code>取得resource URL。按如下顺序查找:
* </p>
* <ol>
* <li>在当前线程的<code>ClassLoader</code>中查找。</li>
* <li>在装入自己的<code>ClassLoader</code>中查找。</li>
* <li>通过<code>ClassLoader.getSystemResource</code>方法查找。</li>
* </ol>
*
* @param resourceName 要查找的资源名,就是以"/"分隔的标识符字符串
* @return resource的URL
*/
public static URL getResource(String resourceName) {
if (resourceName == null) {
return null;
}
ClassLoader classLoader = null;
URL url = null;
// 首先试着从当前线程的ClassLoader中查找。
classLoader = getContextClassLoader();
if (classLoader != null) {
url = classLoader.getResource(resourceName);
if (url != null) {
return url;
}
}
// 如果没找到,试着从装入自己的ClassLoader中查找。
classLoader = ClassLoaderUtil.class.getClassLoader();
if (classLoader != null) {
url = classLoader.getResource(resourceName);
if (url != null) {
return url;
}
}
// 最后的尝试: 在系统ClassLoader中查找(JDK1.2以上),
// 或者在JDK的内部ClassLoader中查找(JDK1.2以下)。
return ClassLoader.getSystemResource(resourceName);
}
/**
* 从指定调用者所属的<code>ClassLoader</code>取得resource URL。
*
* @param resourceName 要查找的资源名,就是以"/"分隔的标识符字符串
* @param referrer 调用者类,如果为<code>null</code>,表示在<code>ClassLoaderUtil</code>
* 的class loader中找。
* @return resource URL,如果没找到,则返回<code>null</code>
*/
public static URL getResource(String resourceName, Class<?> referrer) {
if (resourceName == null) {
return null;
}
ClassLoader classLoader = getReferrerClassLoader(referrer);
return classLoader == null ? ClassLoaderUtil.class.getClassLoader().getResource(resourceName) : classLoader
.getResource(resourceName);
}
/**
* 从指定的<code>ClassLoader</code>取得resource URL。
*
* @param resourceName 要查找的资源名,就是以"/"分隔的标识符字符串
* @param classLoader 在指定classLoader中查找,如果为<code>null</code>,表示在
* <code>ClassLoaderUtil</code>的class loader中找。
* @return resource URL,如果没找到,则返回<code>null</code>
*/
public static URL getResource(String resourceName, ClassLoader classLoader) {
if (resourceName == null) {
return null;
}
return classLoader == null ? ClassLoaderUtil.class.getClassLoader().getResource(resourceName) : classLoader
.getResource(resourceName);
}
/**
* 从<code>ClassLoader</code>取得resource的输入流。 相当于
* <code>getResource(resourceName).openStream()</code>。
*
* @param resourceName 要查找的资源名,就是以"/"分隔的标识符字符串
* @return resource的输入流
*/
public static InputStream getResourceAsStream(String resourceName) {
URL url = getResource(resourceName);
try {
if (url != null) {
return url.openStream();
}
} catch (IOException e) {
// 打开URL失败。
}
return null;
}
/**
* 从<code>ClassLoader</code>取得resource的输入流。 相当于
* <code>getResource(resourceName,
* referrer).openStream()</code>。
*
* @param resourceName 要查找的资源名,就是以"/"分隔的标识符字符串
* @param referrer 调用者类,如果为<code>null</code>,表示在<code>ClassLoaderUtil</code>
* 的class loader中找。
* @return resource的输入流
*/
public static InputStream getResourceAsStream(String resourceName, Class<?> referrer) {
URL url = getResource(resourceName, referrer);
try {
if (url != null) {
return url.openStream();
}
} catch (IOException e) {
// 打开URL失败。
}
return null;
}
/**
* 从<code>ClassLoader</code>取得resource的输入流。 相当于
* <code>getResource(resourceName,
* classLoader).openStream()</code>。
*
* @param resourceName 要查找的资源名,就是以"/"分隔的标识符字符串
* @param classLoader 在指定classLoader中查找,如果为<code>null</code>,表示在
* <code>ClassLoaderUtil</code>的class loader中找。
* @return resource的输入流
*/
public static InputStream getResourceAsStream(String resourceName, ClassLoader classLoader) {
URL url = getResource(resourceName, classLoader);
try {
if (url != null) {
return url.openStream();
}
} catch (IOException e) {
// 打开URL失败。
}
return null;
}
// ==========================================================================
// 查找class的位置。
//
// 类似于UNIX的which方法。
// ==========================================================================
/**
* 从当前线程的<code>ClassLoader</code>中查找指定名称的类。
*
* @param className 要查找的类名
* @return URL数组,列举了系统中所有可找到的同名类,如果未找到,则返回一个空数组
*/
public static URL[] whichClasses(String className) {
return getResources(ClassUtil.getResourceNameForClass(className));
}
/**
* 从当前线程的<code>ClassLoader</code>中查找指定名称的类。
*
* @param className 要查找的类名
* @param referrer 调用者类,如果为<code>null</code>,表示在<code>ClassLoaderUtil</code>
* 的class loader中找。
* @return URL数组,列举了系统中所有可找到的同名类,如果未找到,则返回一个空数组
*/
public static URL[] whichClasses(String className, Class<?> referrer) {
return getResources(ClassUtil.getResourceNameForClass(className), referrer);
}
/**
* 从当前线程的<code>ClassLoader</code>中查找指定名称的类。
*
* @param className 要查找的类名
* @param classLoader 在指定classLoader中查找,如果为<code>null</code>,表示在
* <code>ClassLoaderUtil</code>的class loader中找。
* @return URL数组,列举了系统中所有可找到的同名类,如果未找到,则返回一个空数组
*/
public static URL[] whichClasses(String className, ClassLoader classLoader) {
return getResources(ClassUtil.getResourceNameForClass(className), classLoader);
}
/**
* 从当前线程的<code>ClassLoader</code>中查找指定名称的类。
*
* @param className 要查找的类名
* @return 类文件的URL,如果未找到,则返回<code>null</code>
*/
public static URL whichClass(String className) {
return getResource(ClassUtil.getResourceNameForClass(className));
}
/**
* 从当前线程的<code>ClassLoader</code>中查找指定名称的类。
*
* @param className 要查找的类名
* @param referrer 调用者类,如果为<code>null</code>,表示在<code>ClassLoaderUtil</code>
* 的class loader中找。
* @return 类文件的URL,如果未找到,则返回<code>null</code>
*/
public static URL whichClass(String className, Class<?> referrer) {
return getResource(ClassUtil.getResourceNameForClass(className), referrer);
}
/**
* 从当前线程的<code>ClassLoader</code>中查找指定名称的类。
*
* @param className 要查找的类名
* @param classLoader 在指定classLoader中查找,如果为<code>null</code>,表示在
* <code>ClassLoaderUtil</code>的class loader中找。
* @return 类文件的URL,如果未找到,则返回<code>null</code>
*/
public static URL whichClass(String className, ClassLoader classLoader) {
return getResource(ClassUtil.getResourceNameForClass(className), classLoader);
}
}