JVM

类加载器

1. 启动类加载器

加载 JAVA_HOME\lib 下的 类文件。rt.jar 

2.扩展类加载器和应用程序类加载器,这两个加载器都继承自 

1)public abstract class java.lang.ClassLoader 类

都是 

public class sun.misc.Launcher 的静态内部类
2)static class ExtClassLoader extends URLClassLoader 作为扩展类加载器,主要加载 JAVA_HOME\lib\ext 下的 类
3)static class AppClassLoader extends URLClassLoader 作为 用户应用程序类加载器,主要加载 用户 classpath 下的 class文件,可通过  
ClassLoader 的静态方法 public static ClassLoader getSystemClassLoader() 获取

4)类加载器入口方法

ClassLoader:

public Class<?> loadClass(String name) throws ClassNotFoundException {
    return loadClass(name, false);
}

ClassLoader:

// 该方法在 jdk1.2 之前,都是 作为 重写的。jdk1.2之后 引入 双亲委派模式,加入了 findClass作为 自己的类加载器重写的主要方法

protected Class<?> loadClass(String name, boolean resolve)
    throws ClassNotFoundException
{
    synchronized (getClassLoadingLock(name)) {
        // First, check if the class has already been loaded
        Class<?> c = findLoadedClass(name);
        if (c == null) {
            long t0 = System.nanoTime();
            try {
                if (parent != null) {
                    c = parent.loadClass(name, false);
                } else {
                    c = findBootstrapClassOrNull(name);
                }
            } catch (ClassNotFoundException e) {
                // ClassNotFoundException thrown if class not found
                // from the non-null parent class loader
            }

            if (c == null) {
                // If still not found, then invoke findClass in order
                // to find the class.
                long t1 = System.nanoTime();
                c = findClass(name);

                // this is the defining class loader; record the stats
                sun.misc.PerfCounter.getParentDelegationTime().addTime(t1 - t0);
                sun.misc.PerfCounter.getFindClassTime().addElapsedTimeFrom(t1);
                sun.misc.PerfCounter.getFindClasses().increment();
            }
        }
        if (resolve) {
            resolveClass(c);
        }
        return c;
    }
}
 * @since  1.2
 */
protected Class<?> findClass(String name) throws ClassNotFoundException {
    throw new ClassNotFoundException(name);
}

 

// 同时,在jdk1.2  的 Thread 类中引入了 线程上下文类加载器

 * @since 1.2
 */
public void setContextClassLoader(ClassLoader cl) {
    SecurityManager sm = System.getSecurityManager();
    if (sm != null) {
        sm.checkPermission(new RuntimePermission("setContextClassLoader"));
    }
    contextClassLoader = cl;
}

 

自定义类加载器,需要重写 findClass 方法,需要用 ClassLoader 提供的 defineClass 将读取到的 字节数组 写入内存 返回 Class 对象

 * @since  1.1
 */
protected final Class<?> defineClass(String name, byte[] b, int off, int len)
    throws ClassFormatError
{
    return defineClass(name, b, off, len, null);
}

线程上线文类加载器的应用:在 Apache 的 common log 中有用到。

org.apache.commons.logging.LogFactory

public static LogFactory getFactory() throws LogConfigurationException {
    // Identify the class loader we will be using
    ClassLoader contextClassLoader = getContextClassLoaderInternal();

 

private static ClassLoader getContextClassLoaderInternal() throws LogConfigurationException {
    return (ClassLoader)AccessController.doPrivileged(
        new PrivilegedAction() {
            public Object run() {
                return directGetContextClassLoader();
            }
        });
}

 

protected static ClassLoader directGetContextClassLoader() throws LogConfigurationException {
    ClassLoader classLoader = null;

    try {
        classLoader = Thread.currentThread().getContextClassLoader();
    } catch (SecurityException ex) {
        /**
         * getContextClassLoader() throws SecurityException when
         * the context class loader isn't an ancestor of the
         * calling class's class loader, or if security
         * permissions are restricted.
         *
         * We ignore this exception to be consistent with the previous
         * behavior (e.g. 1.1.3 and earlier).
         */
        // ignore
    }

    // Return the selected class loader
    return classLoader;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值