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 方法来完成类加载。
从上图看双亲委派机制的本质就是由子到父,再由父到子的过程。