JVM启动过程 类加载器

下图来自:http://blog.csdn.net/jiangwei0910410003/article/details/17733153

package com.test.jvm.common;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;

/**
 * 自定义的类加载器
 */
public class MyClassLoader extends ClassLoader {
    private String name; //加载器的名字
//    private String className; //被加载类的全名
    private String path = "D:/workspace/eclipse-workspace64bit17-forPersonalProject/openbank-parent/openbank-test/src/test/java/"; //加载类的路径
    private final String fileType = ".class"; //class文件的扩展名

    public MyClassLoader(String name) {
        super(); //让系统类加载器成为该类加载器的父类
        this.name = name;
    }
    public MyClassLoader(ClassLoader parent,String name) {
        super(parent); //显示指定该类加载器的的父加载器
        this.name = name;
    }
    @Override
    public String toString() {
        // TODO Auto-generated method stub
        return this.name;
    }

    // TODO Auto-generated method stub
    private byte[] loadClassData(String className) {
        InputStream inputStream = null;
        byte[] data = null;
        ByteArrayOutputStream byteArrayOutputStream  = null;
        try {
            className = className.replace(‘.‘, ‘/‘);
            inputStream = new FileInputStream(new File(path+className+fileType));
            byteArrayOutputStream = new ByteArrayOutputStream();
            int ch = 0;
            while(-1 != (ch = inputStream.read())) {
                byteArrayOutputStream.write(ch);
            }
            data = byteArrayOutputStream.toByteArray();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                inputStream.close();
                byteArrayOutputStream.close();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        return data;
    }
    @Override
    protected Class<?> findClass(String className) throws ClassNotFoundException {
        byte[] data =this.loadClassData(className);
        //将字节数组转换成Class对象
        return this.defineClass(className, data, 0, data.length);
    }
    public String getPath() {
        return path;
    }
    public void setPath(String path) {
        this.path = path;
    }
    public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
        System.out.println(System.getProperty("java.class.path"));
        System.out.println("------------------");
        MyClassLoader loader1 = new MyClassLoader("loader1");
//        loader1.setPath("D:/temp/serverlib");
        MyClassLoader loader2 = new MyClassLoader(loader1,"loader2"); //将loader1作为loader2的父加载器
//        loader2.setPath("D:/temp/clientlib");
        MyClassLoader loader3 = new MyClassLoader(null,"loader3"); //将第一个参数设为空表示父加载器为根加载器
//        loader3.setPath("d:/temp/systemlib");
        test(loader2);
        System.out.println("-----------------");
        test(loader3);
    }
    public static void test(ClassLoader loader) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
        Class clazz = loader.loadClass("com.test.jvm.common.Sample");
        Object object = clazz.newInstance();
    }
}
public class Sample {
    public int v1 = 1;
    public Sample() {
        System.out.println("Sample is loaded by: "+this.getClass().getClassLoader());
        new Dog();
    }
}
public class Dog {
    public Dog() {
        System.out.println("Dog is loaded by: "+this.getClass().getClassLoader());
    }
}

我将编译后的Sample.class和Dog.class放在他们源代码所在的包里

运行结果:

D:\workspace\eclipse-workspace64bit17-forPersonalProject\openbank-parent\openbank-test\target\test-classes;D:\workspace\eclipse-workspace64bit17-forPersonalProject\openbank-parent\openbank-test\target\classes;D:\IDE\eclipse\plugins\org.testng.eclipse_6.9.13.201609291640\lib\testng.jar;D:\IDE\eclipse\plugins\org.testng.eclipse_6.9.13.201609291640\lib\jcommander.jar;D:\IDE\eclipse\plugins\org.testng.eclipse_6.9.13.201609291640\lib\bsh-2.0b4.jar;D:\IDE\eclipse\plugins\org.testng.eclipse_6.9.13.201609291640\lib\snakeyaml.jar;D:\workspace\eclipse-workspace64bit17-forPersonalProject\openbank-parent\openbank-batch\target\classes;C:\Users\Ash\.m2\repository\org\springframework\batch\spring-batch-core\3.0.6.RELEASE\spring-batch-core-3.0.6.RELEASE.jar;C:\Users\Ash\.m2\repository\com\ibm\jbatch\com.ibm.jbatch-tck-spi\1.0\com.ibm.jbatch-tck-spi-1.0.jar;C:\Users\Ash\.m2\repository\javax\batch\javax.batch-api\1.0\javax.batch-api-1.0.jar;C:\Users\Ash\.m2\repository\com\thoughtworks\xstream\xstream\1.4.7\xstream-1.4.7.jar;C:\Users\Ash\.m2\repository\xmlpull\xmlpull\1.1.3.1\xmlpull-1.1.3.1.jar;C:\Users\Ash\.m2\repository\xpp3\xpp3_min\1.1.4c\xpp3_min-1.1.4c.jar;C:\Users\Ash\.m2\repository\org\codehaus\jettison\jettison\1.2\jettison-1.2.jar;C:\Users\Ash\.m2\repository\org\springframework\batch\spring-batch-infrastructure\3.0.6.RELEASE\spring-batch-infrastructure-3.0.6.RELEASE.jar;C:\Users\Ash\.m2\repository\org\springframework\retry\spring-retry\1.1.0.RELEASE\spring-retry-1.1.0.RELEASE.jar;C:\Users\Ash\.m2\repository\org\springframework\spring-beans\4.1.9.RELEASE\spring-beans-4.1.9.RELEASE.jar;C:\Users\Ash\.m2\repository\org\springframework\spring-context\4.1.9.RELEASE\spring-context-4.1.9.RELEASE.jar;D:\workspace\eclipse-workspace64bit17-forPersonalProject\openbank-parent\openbank-base\target\classes;C:\Users\Ash\.m2\repository\commons-dbcp\commons-dbcp\1.4\commons-dbcp-1.4.jar;C:\Users\Ash\.m2\repository\commons-pool\commons-pool\1.6\commons-pool-1.6.jar;C:\Users\Ash\.m2\repository\com\oracle\ojdbc6\11.2.0.4\ojdbc6-11.2.0.4.jar;C:\Users\Ash\.m2\repository\junit\junit\3.8.1\junit-3.8.1.jar;C:\Users\Ash\.m2\repository\org\springframework\boot\spring-boot-starter-web\1.2.8.RELEASE\spring-boot-starter-web-1.2.8.RELEASE.jar;C:\Users\Ash\.m2\repository\org\springframework\boot\spring-boot-starter\1.2.8.RELEASE\spring-boot-starter-1.2.8.RELEASE.jar;C:\Users\Ash\.m2\repository\org\springframework\boot\spring-boot\1.2.8.RELEASE\spring-boot-1.2.8.RELEASE.jar;C:\Users\Ash\.m2\repository\org\springframework\boot\spring-boot-autoconfigure\1.2.8.RELEASE\spring-boot-autoconfigure-1.2.8.RELEASE.jar;C:\Users\Ash\.m2\repository\org\springframework\boot\spring-boot-starter-logging\1.2.8.RELEASE\spring-boot-starter-logging-1.2.8.RELEASE.jar;C:\Users\Ash\.m2\repository\org\slf4j\jul-to-slf4j\1.7.13\jul-to-slf4j-1.7.13.jar;C:\Users\Ash\.m2\repository\org\slf4j\log4j-over-slf4j\1.7.13\log4j-over-slf4j-1.7.13.jar;C:\Users\Ash\.m2\repository\ch\qos\logback\logback-classic\1.1.3\logback-classic-1.1.3.jar;C:\Users\Ash\.m2\repository\ch\qos\logback\logback-core\1.1.3\logback-core-1.1.3.jar;C:\Users\Ash\.m2\repository\org\yaml\snakeyaml\1.14\snakeyaml-1.14.jar;C:\Users\Ash\.m2\repository\com\fasterxml\jackson\core\jackson-databind\2.4.6\jackson-databind-2.4.6.jar;C:\Users\Ash\.m2\repository\com\fasterxml\jackson\core\jackson-annotations\2.4.6\jackson-annotations-2.4.6.jar;C:\Users\Ash\.m2\repository\com\fasterxml\jackson\core\jackson-core\2.4.6\jackson-core-2.4.6.jar;C:\Users\Ash\.m2\repository\org\hibernate\hibernate-validator\5.1.3.Final\hibernate-validator-5.1.3.Final.jar;C:\Users\Ash\.m2\repository\javax\validation\validation-api\1.1.0.Final\validation-api-1.1.0.Final.jar;C:\Users\Ash\.m2\repository\org\jboss\logging\jboss-logging\3.1.3.GA\jboss-logging-3.1.3.GA.jar;C:\Users\Ash\.m2\repository\com\fasterxml\classmate\1.0.0\classmate-1.0.0.jar;C:\Users\Ash\.m2\repository\org\springframework\spring-core\4.1.9.RELEASE\spring-core-4.1.9.RELEASE.jar;C:\Users\Ash\.m2\repository\org\springframework\spring-web\4.1.9.RELEASE\spring-web-4.1.9.RELEASE.jar;C:\Users\Ash\.m2\repository\org\springframework\spring-webmvc\4.1.9.RELEASE\spring-webmvc-4.1.9.RELEASE.jar;C:\Users\Ash\.m2\repository\org\springframework\spring-expression\4.1.9.RELEASE\spring-expression-4.1.9.RELEASE.jar;C:\Users\Ash\.m2\repository\org\springframework\boot\spring-boot-starter-batch\1.2.8.RELEASE\spring-boot-starter-batch-1.2.8.RELEASE.jar;C:\Users\Ash\.m2\repository\org\hsqldb\hsqldb\2.3.3\hsqldb-2.3.3.jar;C:\Users\Ash\.m2\repository\org\springframework\spring-jdbc\4.1.9.RELEASE\spring-jdbc-4.1.9.RELEASE.jar;C:\Users\Ash\.m2\repository\org\springframework\boot\spring-boot-starter-jetty\1.2.8.RELEASE\spring-boot-starter-jetty-1.2.8.RELEASE.jar;C:\Users\Ash\.m2\repository\org\eclipse\jetty\jetty-jsp\9.2.14.v20151106\jetty-jsp-9.2.14.v20151106.jar;C:\Users\Ash\.m2\repository\org\eclipse\jetty\toolchain\jetty-schemas\3.1.M0\jetty-schemas-3.1.M0.jar;C:\Users\Ash\.m2\repository\javax\servlet\javax.servlet-api\3.1.0\javax.servlet-api-3.1.0.jar;C:\Users\Ash\.m2\repository\javax\servlet\jsp\javax.servlet.jsp-api\2.3.1\javax.servlet.jsp-api-2.3.1.jar;C:\Users\Ash\.m2\repository\org\glassfish\web\javax.servlet.jsp\2.3.2\javax.servlet.jsp-2.3.2.jar;C:\Users\Ash\.m2\repository\org\eclipse\jetty\orbit\javax.servlet.jsp.jstl\1.2.0.v201105211821\javax.servlet.jsp.jstl-1.2.0.v201105211821.jar;C:\Users\Ash\.m2\repository\org\glassfish\web\javax.servlet.jsp.jstl\1.2.2\javax.servlet.jsp.jstl-1.2.2.jar;C:\Users\Ash\.m2\repository\org\glassfish\javax.el\3.0.0\javax.el-3.0.0.jar;C:\Users\Ash\.m2\repository\org\eclipse\jetty\orbit\org.eclipse.jdt.core\3.8.2.v20130121\org.eclipse.jdt.core-3.8.2.v20130121.jar;C:\Users\Ash\.m2\repository\org\eclipse\jetty\jetty-webapp\9.2.14.v20151106\jetty-webapp-9.2.14.v20151106.jar;C:\Users\Ash\.m2\repository\org\eclipse\jetty\jetty-xml\9.2.14.v20151106\jetty-xml-9.2.14.v20151106.jar;C:\Users\Ash\.m2\repository\org\eclipse\jetty\jetty-util\9.2.14.v20151106\jetty-util-9.2.14.v20151106.jar;C:\Users\Ash\.m2\repository\org\eclipse\jetty\jetty-servlet\9.2.14.v20151106\jetty-servlet-9.2.14.v20151106.jar;C:\Users\Ash\.m2\repository\org\eclipse\jetty\jetty-security\9.2.14.v20151106\jetty-security-9.2.14.v20151106.jar;C:\Users\Ash\.m2\repository\org\eclipse\jetty\jetty-server\9.2.14.v20151106\jetty-server-9.2.14.v20151106.jar;C:\Users\Ash\.m2\repository\org\eclipse\jetty\websocket\websocket-server\9.2.14.v20151106\websocket-server-9.2.14.v20151106.jar;C:\Users\Ash\.m2\repository\org\eclipse\jetty\websocket\websocket-common\9.2.14.v20151106\websocket-common-9.2.14.v20151106.jar;C:\Users\Ash\.m2\repository\org\eclipse\jetty\websocket\websocket-api\9.2.14.v20151106\websocket-api-9.2.14.v20151106.jar;C:\Users\Ash\.m2\repository\org\eclipse\jetty\jetty-io\9.2.14.v20151106\jetty-io-9.2.14.v20151106.jar;C:\Users\Ash\.m2\repository\org\eclipse\jetty\websocket\websocket-client\9.2.14.v20151106\websocket-client-9.2.14.v20151106.jar;C:\Users\Ash\.m2\repository\org\eclipse\jetty\websocket\websocket-servlet\9.2.14.v20151106\websocket-servlet-9.2.14.v20151106.jar;C:\Users\Ash\.m2\repository\org\eclipse\jetty\jetty-http\9.2.14.v20151106\jetty-http-9.2.14.v20151106.jar;C:\Users\Ash\.m2\repository\org\eclipse\jetty\websocket\javax-websocket-server-impl\9.2.14.v20151106\javax-websocket-server-impl-9.2.14.v20151106.jar;C:\Users\Ash\.m2\repository\org\eclipse\jetty\jetty-annotations\9.2.14.v20151106\jetty-annotations-9.2.14.v20151106.jar;C:\Users\Ash\.m2\repository\org\eclipse\jetty\jetty-plus\9.2.14.v20151106\jetty-plus-9.2.14.v20151106.jar;C:\Users\Ash\.m2\repository\org\eclipse\jetty\jetty-jndi\9.2.14.v20151106\jetty-jndi-9.2.14.v20151106.jar;C:\Users\Ash\.m2\repository\javax\annotation\javax.annotation-api\1.2\javax.annotation-api-1.2.jar;C:\Users\Ash\.m2\repository\org\ow2\asm\asm\5.0.1\asm-5.0.1.jar;C:\Users\Ash\.m2\repository\org\ow2\asm\asm-commons\5.0.1\asm-commons-5.0.1.jar;C:\Users\Ash\.m2\repository\org\ow2\asm\asm-tree\5.0.1\asm-tree-5.0.1.jar;C:\Users\Ash\.m2\repository\org\eclipse\jetty\websocket\javax-websocket-client-impl\9.2.14.v20151106\javax-websocket-client-impl-9.2.14.v20151106.jar;C:\Users\Ash\.m2\repository\javax\websocket\javax.websocket-api\1.0\javax.websocket-api-1.0.jar;C:\Users\Ash\.m2\repository\org\springframework\data\spring-data-redis\1.7.0.RELEASE\spring-data-redis-1.7.0.RELEASE.jar;C:\Users\Ash\.m2\repository\org\springframework\data\spring-data-keyvalue\1.1.0.RELEASE\spring-data-keyvalue-1.1.0.RELEASE.jar;C:\Users\Ash\.m2\repository\org\springframework\data\spring-data-commons\1.9.4.RELEASE\spring-data-commons-1.9.4.RELEASE.jar;C:\Users\Ash\.m2\repository\org\springframework\spring-tx\4.1.9.RELEASE\spring-tx-4.1.9.RELEASE.jar;C:\Users\Ash\.m2\repository\org\springframework\spring-oxm\4.1.9.RELEASE\spring-oxm-4.1.9.RELEASE.jar;C:\Users\Ash\.m2\repository\org\springframework\spring-aop\4.1.9.RELEASE\spring-aop-4.1.9.RELEASE.jar;C:\Users\Ash\.m2\repository\aopalliance\aopalliance\1.0\aopalliance-1.0.jar;C:\Users\Ash\.m2\repository\org\springframework\spring-context-support\4.1.9.RELEASE\spring-context-support-4.1.9.RELEASE.jar;C:\Users\Ash\.m2\repository\org\slf4j\slf4j-api\1.7.19\slf4j-api-1.7.19.jar;C:\Users\Ash\.m2\repository\org\slf4j\jcl-over-slf4j\1.7.13\jcl-over-slf4j-1.7.13.jar;C:\Users\Ash\.m2\repository\redis\clients\jedis\2.8.0\jedis-2.8.0.jar;C:\Users\Ash\.m2\repository\org\apache\commons\commons-pool2\2.2\commons-pool2-2.2.jar;C:\Users\Ash\.m2\repository\org\springframework\boot\spring-boot-starter-test\1.2.8.RELEASE\spring-boot-starter-test-1.2.8.RELEASE.jar;C:\Users\Ash\.m2\repository\org\mockito\mockito-core\1.10.19\mockito-core-1.10.19.jar;C:\Users\Ash\.m2\repository\org\objenesis\objenesis\2.1\objenesis-2.1.jar;C:\Users\Ash\.m2\repository\org\hamcrest\hamcrest-core\1.3\hamcrest-core-1.3.jar;C:\Users\Ash\.m2\repository\org\hamcrest\hamcrest-library\1.3\hamcrest-library-1.3.jar;C:\Users\Ash\.m2\repository\org\springframework\spring-test\4.1.9.RELEASE\spring-test-4.1.9.RELEASE.jar;C:\Users\Ash\.m2\repository\org\testng\testng\6.9.10\testng-6.9.10.jar;C:\Users\Ash\.m2\repository\com\beust\jcommander\1.48\jcommander-1.48.jar;C:\Users\Ash\.m2\repository\org\beanshell\bsh\2.0b4\bsh-2.0b4.jar
------------------
Sample is loaded by: [email protected]
Dog is loaded by: [email protected]
-----------------
Sample is loaded by: loader3
Dog is loaded by: loader3

如果我将Sample.class和Dog.class放在非System.getProperty("java.class.path")路径下,则AppClassLoader将无法找到这个类,则加载这个类的任务将落在自定义类加载器身上,那么上面的输出结果将会不同

时间: 2024-10-23 09:06:16

JVM启动过程 类加载器的相关文章

JVM启动过程

JVM启动过程包括:加载.连接.初始化 1.加载:就是将class文件加载到内存.详细的说是,将class文件加载到运行时数据区的方法区内,然后在堆区创建一个java.lang.Class对象,用来封装类在方法区类的数据结构 有两种类型的类加载器:  1.1JVM自带提供的三类加载器:根类加载器Bootstrap Classloader(C++写的, 程序员无法在JAVA代码中获得该类)   扩展加载器Extension Classloader,使用Java代码实现   系统加载器System

Java虚拟机笔记 – JVM 自定义的类加载器的实现和使用2

1.用户自定义的类加载器: 要创建用户自己的类加载器,只需要扩展java.lang.ClassLoader类,然后覆盖它的findClass(String name)方法即可,该方法根据参数指定类的名字,返回对应的Class对象的引用. findClass protected Class<?> findClass(String name) throws ClassNotFoundException 使用指定的二进制名称查找类.此方法应该被类加载器的实现重写,该实现按照委托模型来加载类.在通过父

Java虚拟机JVM学习05 类加载器的父委托机制

Java虚拟机JVM学习05 类加载器的父委托机制 类加载器 类加载器用来把类加载到Java虚拟机中. 类加载器的类型 有两种类型的类加载器: 1.JVM自带的加载器: 根类加载器(Bootstrap) 扩展类加载器(Extension) 系统类加载器(System) 2.用户自定义的类加载器: java.lang.ClassLoader的子类,用户可以定制类的加载方式. JVM自带的加载器 Java虚拟机自带了以下几种加载器. 1.根(Bootstrap)类加载器: 该加载器没有父加载器. 它

Java虚拟机笔记 – JVM 自定义的类加载器的实现和使用

1.用户自定义的类加载器: 要创建用户自己的类加载器,只需要扩展java.lang.ClassLoader类,然后覆盖它的findClass(String name)方法即可,该方法根据参数指定类的名字,返回对应的Class对象的引用. findClass protected Class<?> findClass(String name) throws ClassNotFoundException 使用指定的二进制名称查找类.此方法应该被类加载器的实现重写,该实现按照委托模型来加载类.在通过父

【深入理解JVM】:类加载器与双亲委派模型

类加载器 加载类的开放性 类加载器(ClassLoader)是Java语言的一项创新,也是Java流行的一个重要原因.在类加载的第一阶段"加载"过程中,需要通过一个类的全限定名来获取定义此类的二进制字节流,完成这个动作的代码块就是类加载器.这一动作是放在Java虚拟机外部去实现的,以便让应用程序自己决定如何获取所需的类. 虚拟机规范并没有指明二进制字节流要从一个Class文件获取,或者说根本没有指明从哪里获取.怎样获取.这种开放使得Java在很多领域得到充分运用,例如: 从ZIP包中读

JVM学习记录-类加载器

前言 JVM设计团队把类加载阶段中的“通过一个类的全限定名来获取描述此类的二进制字节流”这个动作房东Java虚拟机外面去实现,以便让应用程序自己决定如何去获取所需要的类.实现这个动作的代码模块称为“类加载器”. 类与类加载器 类加载器虽然只用户实现类的加载动作,但它在Java程序中起到的作用却远远不限于类加载阶段.每个类都有一个独立的类名称空间,在比较两个类是否“相等”,只有两个类是由同一个类加载器加载的前提下才有意义,否则即使两个类来源于同一个Class文件,被同一个虚拟机加载,只要加载它们的

JVM初识-java类加载器

前言作为一位java开发人员,不懂java虚拟机规范是会被人鄙视的,特别是工作了多年的程序人员.为了不让他人有鄙视的机会,于是本人开始了JVM的学习之旅. 学习Java虚拟机,从了解JVM内存模型开始. JVM[java虚拟机规范]内存模型图 1. Class files一般而言,我们都会将逻辑代码编写在以.java为后缀的文件中.class文件则是由java文件编译[使用javac命令编译]而成. 2. 类加载器子系统 class文件已经有了,那么class文件又是如何加载进虚拟机的呢?这时不

JVM探究之 —— 类加载器-双亲委派模型

虚拟机设计团队把类加载阶段中的“通过一个类的全限定名来获取描述此类的二进制字节流”这个动作放到Java虚拟机外部去实现,以便让应用程序自己决定如何去获取所需要的类.实现这个动作的代码模块称为“类加载器”. 1. 类与类加载器 类加载器虽然只用于实现类的加载动作,但它在Java程序中起到的作用却远远不限于类加载阶段.对于任意一个类,都需要由加载它的类加载器和这个类本身一同确立其在Java虚拟机中的唯一性,每一个类加载器,都拥有一个独立的类名称空间. JVM 中内置了三个重要的 ClassLoade

JVM自定义类加载器加载指定classPath下的所有class及jar

一.JVM中的类加载器类型 从Java虚拟机的角度讲,只有两种不同的类加载器:启动类加载器和其他类加载器. 1.启动类加载器(Boostrap ClassLoader):这个是由c++实现的,主要负责JAVA_HOME/lib目录下的核心 api 或 -Xbootclasspath 选项指定的jar包装入工作. 2.其他类加载器:由java实现,可以在方法区找到其Class对象.这里又细分为几个加载器 a).扩展类加载器(Extension ClassLoader):负责用于加载JAVA_HOM