JVM加载机制之自定义加类加载器

  在JVM类加载器分类中提及JVM自带的加载器无法满足实际业务需求时,可以自定义加载器。那一般什么情况下需要自定义加载器呢?

    • 隔离加载类:模块隔离——把类加载到不同的应用选项中,比如Tomcat类加载器。
    • 修改类加载方式:平台提供了三类加载器除必须加载的类加载器,可以根据实际情况按需动态加载。
    • 扩展加载源:比如还可以从数据库、网络、或其他终端上加载。
    • 防止源码泄漏:java代码容易被编译和篡改,可以进行编译加密,类加载需要自定义还原加密字节码。

  自定义类加载器中方法如何调用呢?在JVM类加载器ClassLoader源码剖析对平台提供的类加载器各方法有了一定了了解大致如下:

                

  对上图中三个方法,可以通过重写loadClass和findClass方法对类加载器按需自定义(defineClass使用final修饰不可重写,只能继承):

    1)重写loadClass方法(是实现双亲委派逻辑的地方,修改他会破坏委派机制,不推荐)
    2)重写findClass方法 (推荐)

  下面示例重写findClass方法自定义类加载器,同时调试跟踪是否实现了自定义功能:

                

                

                

  测试:

                

  跟踪调试分析MyClassLoader:

         

                

                

  上图中查找加载内容的过程就是双亲委派机制:

    1. 首先,检查一下指定名称的类是否已经加载过,如果加载过了,就不需要再加载,直接返回。
    2. 如果此类没有加载过,那么,再判断一下是否有父加载器;如果有父加载器,则由父加载器加载(即调用 parent.loadClass(name, false).或者是调用 bootstrap 类加载器来加载。
    3. 如果父加载器及 bootstrap 类加载器都没有找到指定的类,那么调用当前类加载器的 findClass 方法来完成类加载。

                

  从上图看双亲委派机制的本质就是由子到父,再由父到子的过程。

 

posted on 2024-05-13 15:05  池塘里洗澡的鸭子  阅读(19)  评论(0编辑  收藏  举报