JVM自定义类加载器

时间:2022-07-22
本文章向大家介绍JVM自定义类加载器,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

默认类加载器:Bootstrap ClassLoader --> Extension ClassLoader --> Application ClassLoader

  • Bootstrap ClassLoader:顶层类加载器,负责加载Java基础类,主要是 {JRE_HOME}/lib 下面的 rt.jar,resources.jar,charset.jar和class等。
  • Extension ClassLoader:第二层加载器,负责加载Java扩展类,主要是 {JRE_HOME}/lib/ext 下面的jar和class
  • Application ClassLoader:负责加载当前Java应用的classpath中的所有类

其中Bootstrap ClassLoader是JVM级别的,由C++编写。Extension ClassLoader、Application ClassLoader都是Java类。

Bootstrap ClassLoader由JVM启动,然后初始化sun.misc.Launcher,Launcher初始化Extension ClassLoader、Application ClassLoader。

由于一些特殊的需求:如①加密:Java代码很容易被反编译,如果想对自己的代码进行加密。可先将编译后的代码进行加密,然后再由自定义ClassLoader先解密,然后再加载类。②从非标准来源加载类:可以在自定义ClassLoader中,从指定的来源加载类。

自定义ClassLoader

自定义ClassLoader需要继承java.lang.ClassLoader抽象类,重写findClass方法,在findClass方法中调用defindClass。

ClassLoader创建时,如果没有指定parent,默认为Application ClassLoader

示例

官方示例

可以在java.lang.ClassLoader类中的注释发现该代码

ClassLoader loader = new NetworkClassLoader(host, port);
Object main = loader.loadClass("Main", true).newInstance();
class NetworkClassLoader extends ClassLoader {
    String host;
    int port;
    
    public Class findClass(String name) {
        byte[] b = loadClassData(name);
        return defineClass(name, b, 0, b.length);
    }
    
    private byte[] loadClassData(String data) {
        // load the class data from the connection
    }
}