All Downloads are FREE. Search and download functionalities are using the official Maven repository.

cn.featherfly.common.lang.ClassLoaderUtils Maven / Gradle / Ivy


/*
 * Thgk-Commons
 *
 * created on May 21, 2010 12:06:27 AM
 */
package cn.featherfly.common.lang;

import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.NoSuchElementException;
import java.util.Set;

/**
 * 

* 类加载器工具 *

* * @author 钟冀 * @since 1.0 * @version 1.0 */ public final class ClassLoaderUtils { private ClassLoaderUtils() { } private static final String ENTER = "\n"; private static final String TAB = "\t"; /** * 加载给定名称的所有资源,将搜索类加载器或得的所有结果汇总. * 如果没有发现结果,如果资源文件不是以'/'开头,则在资源名称前加前缀'/',并再次查找。 * * 此方法将尝试加载资源的顺序如下: *
    *
  • Thread.currentThread().getContextClassLoader() *
  • ResourceLoader.class.getClassLoader() *
  • callingClass.getClassLoader() *
* * @param resourceName 需要加载的资源名称 * @param callingClass 调用对象的class * @param aggregate aggregate * @throws IOException IO异常 * @return 资源路径的迭代器 */ public static Iterator getResources(String resourceName, Class callingClass , boolean aggregate) throws IOException { AggregateIterator iterator = new AggregateIterator(); iterator.addEnumeration(Thread.currentThread().getContextClassLoader().getResources(resourceName)); if (!iterator.hasNext() || aggregate) { iterator.addEnumeration(ClassLoaderUtils.class.getClassLoader().getResources(resourceName)); } if (!iterator.hasNext() || aggregate) { ClassLoader cl = callingClass.getClassLoader(); if (cl != null) { iterator.addEnumeration(cl.getResources(resourceName)); } } if (!iterator.hasNext() && (resourceName != null) && (resourceName.charAt(0) != '/')) { return getResources('/' + resourceName, callingClass, aggregate); } return iterator; } /** * 加载给定的资源. * * 此方法将尝试加载资源的顺序如下: *
    *
  • 从 Thread.currentThread().getContextClassLoader() 加载 *
  • 从 ResourceLoader.class.getClassLoader() 加载 *
  • callingClass.getClassLoader() *
* * @param resourceName 需要加载的资源名称 * @param callingClass 调用对象的class * @return 资源路径 */ public static URL getResource(String resourceName, Class callingClass) { URL url = Thread.currentThread().getContextClassLoader().getResource(resourceName); if (url == null) { url = ClassLoaderUtils.class.getClassLoader().getResource(resourceName); } if (url == null) { ClassLoader cl = callingClass.getClassLoader(); if (cl != null) { url = cl.getResource(resourceName); } } if ((url == null) && (resourceName != null) && (resourceName.charAt(0) != '/')) { return getResource('/' + resourceName, callingClass); } return url; } /** * 这是一个用来方便的加载流资源的方法. * * 用于查找资源的算法在getResource()中给出了 * * @param resourceName 需要加载的资源名称 * @param callingClass 调用对象的class * @return 资源输入流 */ public static InputStream getResourceAsStream(String resourceName, Class callingClass) { URL url = getResource(resourceName, callingClass); try { return (url != null) ? url.openStream() : null; } catch (IOException e) { return null; } } /** * 使用传入的名称加载类(class). * * 加载的顺序如下所示: *
    *
  • 从 Thread.currentThread().getContextClassLoader() 加载 *
  • 使用 Class.forName() 加载 *
  • 从 ResourceLoader.class.getClassLoader() 加载 *
  • callingClass.getClassLoader() *
* * @param className 需要加载的类(class)名称 * @param callingClass 调用类或对象的class属性 * @throws ClassNotFoundException 如果从以上提供的几个地方都未加载到,则抛出. * @return 加载的类 */ public static Class loadClass(String className, Class callingClass) throws ClassNotFoundException { try { return (Class) Thread.currentThread().getContextClassLoader().loadClass(className); } catch (ClassNotFoundException e) { try { return (Class) Class.forName(className); } catch (ClassNotFoundException ex) { try { return (Class) ClassLoaderUtils.class.getClassLoader().loadClass(className); } catch (ClassNotFoundException exc) { return (Class) callingClass.getClassLoader().loadClass(className); } } } } /** * 打印输出当前类加载器的层次结构 - 调试很有用. */ public static void printClassLoader() { System.out.println("ClassLoaderUtils.printClassLoader"); printClassLoader(Thread.currentThread().getContextClassLoader()); } /** * 打印输出给定类加载器的层次结构 - 调试很有用 * @param cl 给定的类加载器 */ public static void printClassLoader(ClassLoader cl) { System.out.println("ClassLoaderUtils.printClassLoader(cl = " + cl + ")"); if (cl != null) { printClassLoader(cl.getParent()); } } /** * 显示类加载器的层次结构. * 使用默认换行符和制表符的文本字符. * * @param obj 对象层次结构的分析装载机 * @param role 当前类在应用程序中作用的说明 * (例如,"servlet"或"EJB"的引用) * @return 一个字符串,显示这个类的类加载器层次结构 */ public static String showClassLoaderHierarchy(Object obj, String role) { return showClassLoaderHierarchy(obj, role, ENTER, TAB); } /** * 显示类加载器的层次结构. * @param obj 对象层次结构的分析装载机 * @param role 当前类在应用程序中作用的说明 * (例如,"servlet"或"EJB"的引用) * @param lineBreak 设置断行符 * @param tabText 设置tabText文本使用的标签 * @return 一个字符串,显示这个类的类加载器层次结构 */ public static String showClassLoaderHierarchy(Object obj, String role, String lineBreak, String tabText) { String s = "object of " + obj.getClass() + ": role is " + role + lineBreak; return s + showClassLoaderHierarchy(obj.getClass().getClassLoader(), lineBreak, tabText, 0); } /** * 显示给定类加载器的层次结构. * 使用默认换行符和制表符的文本字符. * @param cl 需要分析的classLoader * @return 一个字符串,显示这个类的类加载器层次结构 */ public static String showClassLoaderHierarchy(ClassLoader cl) { return showClassLoaderHierarchy(cl, ENTER, TAB); } /** * 显示给定类加载器的层次结构. * @param cl 需要分析的classLoader * @param lineBreak 设置断行符 * @param tabText 设置tabText文本使用的标签 * @return 一个字符串,显示这个类的类加载器层次结构 */ public static String showClassLoaderHierarchy(ClassLoader cl, String lineBreak, String tabText) { return showClassLoaderHierarchy(cl, lineBreak, tabText, 0); } /** * 显示给定类加载器的层次结构. * @param c1 需要分析的classLoader * @param lineBreak 设置断行符 * @param tabText 设置tabText文本使用的标签 * @param indent 当前loader的嵌套级别(从0开始);用于格式化打印输出 * @return 一个字符串,显示这个类的类加载器层次结构 */ private static String showClassLoaderHierarchy(ClassLoader cl, String lineBreak, String tabText, int indent) { if (cl == null) { ClassLoader ccl = Thread.currentThread().getContextClassLoader(); return "context class loader=[" + ccl + " ] hashCode=" + ccl.hashCode(); } StringBuffer buf = new StringBuffer(); for (int i = 0; i < indent; i++) { buf.append(tabText); } buf.append("[").append(cl).append("] hashCode=").append(cl.hashCode()).append(lineBreak); ClassLoader parent = cl.getParent(); return buf.toString() + showClassLoaderHierarchy(parent, lineBreak, tabText, indent + 1); } /** * 聚合成一个能进行重复迭代和过滤的枚举实例。 * 始终保持一领先的统计员,以防止重复返回。 */ protected static class AggregateIterator implements Iterator { LinkedList> enums = new LinkedList>(); Enumeration cur = null; E next = null; Set loaded = new HashSet(); @SuppressWarnings("rawtypes") public AggregateIterator addEnumeration(Enumeration e) { if (e.hasMoreElements()) { if (cur == null) { cur = e; next = e.nextElement(); loaded.add(next); } else { enums.add(e); } } return this; } @Override public boolean hasNext() { return (next != null); } @Override public E next() { if (next != null) { E prev = next; next = loadNext(); return prev; } else { throw new NoSuchElementException(); } } private Enumeration determineCurrentEnumeration() { if (cur != null && !cur.hasMoreElements()) { if (enums.size() > 0) { cur = enums.removeLast(); } else { cur = null; } } return cur; } private E loadNext() { if (determineCurrentEnumeration() != null) { E tmp = cur.nextElement(); while (loaded.contains(tmp)) { tmp = loadNext(); if (tmp == null) { break; } } if (tmp != null) { loaded.add(tmp); } return tmp; } return null; } @Override public void remove() { throw new UnsupportedOperationException(); } } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy