JVM 自定义类加载器在复杂类情况下的运行分析

一、自定义类加载器在复杂类情况下的运行分析

1、使用之前创建的类加载器

public class MyTest16  extends  ClassLoader{

    private String className;

    //目录
     private String path;

    private final String fileExtension = ".class";

    public MyTest16(String classLoadName){
        super(); //将系统类加载器当做该类加载器的父加载器
        this.className = classLoadName;
    }

    public MyTest16(ClassLoader parent, String classLoadName){
        super(parent); //显示指定该类加载器的父加载器器
        this.className = classLoadName;
    }

    public void setPath(String path) {
        this.path = path;
    }

    @Override
    public String toString() {
        return "[" + this.className + "]";
    }

    @Override
    protected Class<?> findClass(String clasName) throws ClassNotFoundException {
        System.out.println("findClass invoked:" + clasName);
        System.out.println("class loader name: " + this.className);
        byte[] data = this.loadClassData(clasName);
        return  this.defineClass(clasName,data, 0, data.length);
    }

    private byte[] loadClassData(String className){
        InputStream is = null;
        byte[] data = null;
        ByteArrayOutputStream baos = null;

        try{
            className = className.replace(".","//");
            //System.out.println("className:" +this.className);
            is = new FileInputStream(new File(this.path + className + this.fileExtension));
            baos = new ByteArrayOutputStream();
            int ch = 0;
            while ( -1 != (ch = is.read())){
                baos.write(ch);
            }
            data = baos.toByteArray();

        }catch (Exception ex){
            ex.printStackTrace();
        }finally {
            try {
                is.close();
                baos.close();
            }catch (Exception ex){
                ex.printStackTrace();
            }
        }

        return  data;

    }

   


}

  

2、创建MyCat类

public class MyCat {
    public MyCat(){
        System.out.println("MyCat is loaded by:" + this.getClass().getClassLoader());
    }
}

  

3、创建MySample类

public class MySample {

    public MySample(){
        System.out.println("MySample is loaded by:" + this.getClass().getClassLoader());
        new MyCat();

    }
}

  

4、创建测试类

public class MyTest17 {
    public static void main(String[] args)  throws  Exception{
        MyTest16 loader1 = new MyTest16("loader1");

        Class<?> clazz = loader1.loadClass("com.example.jvm.classloader.MySample");

        System.out.println("class:" + clazz.hashCode());

        //如果注释掉改行,那么并不会实例化MySample对象,即MySample构造方法不会被调用
        //因此不会实例化MyCat对象,即没有对MyCat进行主动使用,这里就不会加重MyCat Class
        Object object = clazz.newInstance();



    }
}

  

打印结果

class:1735600054
MySample is loaded by:sun.misc.Launcher$AppClassLoader@18b4aac2
MyCat is loaded by:sun.misc.Launcher$AppClassLoader@18b4aac2

  

增加-XX:+TraceClassLoading后的打印结果

 

 

如果去掉Object object = clazz.newInstance();

打印结果为

说明:如果注释掉Object object = clazz.newInstance();该行,那么并不会实例化MySample对象,即MySample构造方法不会被调用

         因此不会实例化MyCat对象,即没有对MyCat进行主动使用,这里就不会加载MyCat Class。

         而且这个例子说明MyCat没有被预先加载

 

 

二、对一的Code进行改造

在一的基础上,新建一个测试类

public class MyTest17_1 {
    public static void main(String[] args)  throws  Exception{
        MyTest16 loader1 = new MyTest16("loader1");
        loader1.setPath("D:/temp/");
        Class<?> clazz = loader1.loadClass("com.example.jvm.classloader.MySample");

        System.out.println("class:" + clazz.hashCode());

        //如果注释掉该行,那么并不会实例化MySample对象,即MySample构造方法不会被调用
        //因此不会实例化MyCat对象,即没有对MyCat进行主动使用,这里就不会加载MyCat Class
        Object object = clazz.newInstance();



    }
}

  里面增加了一个方法loader1.setPath("D:/temp/");

 

然后将MyCat.class 和MySample.class 剪切到D:/temp/目录下,如下面两图

 

 

打印结果:

findClass invoked:com.example.jvm.classloader.MySample
class loader name: loader1
class:2133927002
MySample is loaded by:[loader1]
findClass invoked:com.example.jvm.classloader.MyCat
class loader name: loader1
MyCat is loaded by:[loader1]

  

相关文章

Mycat是什么?MyCat是一个开源的分布式数据库系统,是一个实...
转自:https://www.cnblogs.com/ivictor/p/5111495.html参考...
1.在数据库做好主从同步的情况下搭建mycat。下载mycat,解压...
集群的服务器列表在10.11.0.210和10.11.0.216中部署mycat和h...
Mycat是什么?·一个彻底开源的,面向企业应用开发的大数据库...
<system>配置Mycat系统参数 <system>  <p...