Java ClassLoader基础及加载不同依赖 Jar 中的公共类
来源:互联网 发布:手机迅雷极速优化版 编辑:程序博客网 时间:2024/05/21 01:46
本文主要介绍 ClassLoader 的基础知识,ClassLoader 如何动态加载 Jar,ClassLoader 隔离问题及如何加载不同 Jar 中的公共类。
本文工程开源地址见:Java Dynamic Load Jar@Github,Clone 以后直接以 Java Application去运行 java-dynamic-loader-host 工程即可。
其实本文只是 Android 插件化的一个引子,做过 Android 插件化的同学,可以试试对于 Android Support 包中的 FragmentActivity 和 ActionBarActivity 怎么像一般的 Activity 一样被代理,挺有意思。
1. ClassLoader 的基础知识
无论是 JVM 还是 Dalvik 都是通过 ClassLoader 去加载所需要的类,而 ClassLoader 加载类的方式常称为双亲委托,ClassLoader.java 具体代码如下:
从上面加载类的顺序中我们可以知道,loadClass 会先看这个类是不是已经被 loaded 过,没有的话则去他的 parent 去找,如此递归,称之为双亲委托。
2. 动态加载 Jar
Java 中动态加载 Jar 比较简单,如下:
表示加载 libs 下面的 jar1.jar,其中 parentLoader 就是上面1中的 parent,可以为当前的 ClassLoader。
3. ClassLoader 隔离问题
大家觉得一个运行程序中有没有可能同时存在两个包名和类名完全一致的类?
JVM 及 Dalvik 对类唯一的识别是 ClassLoader id + PackageName + ClassName,所以一个运行程序中是有可能存在两个包名和类名完全一致的类的。并且如果这两个”类”不是由一个 ClassLoader 加载,是无法将一个类的示例强转为另外一个类的,这就是 ClassLoader 隔离。 如 Android 中碰到如下异常
当碰到这种问题时可以通过 instance.getClass().getClassLoader(); 得到 ClassLoader,看 ClassLoader 是否一样。
4. 加载不同 Jar 包中公共类
现在 Host 工程包含了 common.jar, jar1.jar, jar2.jar,并且 jar1.jar 和 jar2.jar 都包含了 common.jar,我们通过 ClassLoader 将 jar1, jar2 动态加载进来,这样在 Host 中实际是存在三份 common.jar,如下图:
我们怎么保证 common.jar 只有一份而不会造成上面3中提到的 ClassLoader 隔离的问题呢,其实很简单,有三种方式:
第一种:我们只要让加载 jar1 和 jar2 的 ClassLoader 的 parent 为同一个 ClassLoader,并且该 ClassLoader 加载过 common.jar,通过上面 1 中我们知道根据双亲委托,最后都会首先被 parentClassLoader加载。
第二种:我们重写 jar1 和 jar2 的 ClassLoader,在 loadClass 函数中我们先去某个含有 common.jar 的 ClassLoader 中 load 即可,其实就是把上面的 parentClassLoader 换掉了而已。
第三种:在生成 jar1 和 jar2 时把 common.jar 去掉,只保留 host 中一份,以 host ClassLoader 为 parentClassLoader 即可。
具体可见代码:JarClassLoader
代码地址:https://github.com/Trinea/java-dynamic-load-jar/blob/master/java-dynamic-loader-host%2Fsrc%2Fcn%2Ftrinea%2Fjava%2Fdynamic%2Fload%2Fhost%2Floader%2FJarClassLoader.java
- Java ClassLoader基础及加载不同依赖 Jar 中的公共类
- Java ClassLoader基础及加载不同依赖 Jar 中的公共类
- Java ClassLoader基础及加载不同依赖 Jar 中的公共类
- Java ClassLoader基础及加载不同依赖 Jar 中的公共类
- Java ClassLoader基础及加载不同依赖 Jar 中的公共类
- Java ClassLoader基础及加载不同依赖 Jar 中的公共类
- Java ClassLoader基础及加载不同依赖 Jar 中的公共类
- Java ClassLoader加载.jar包中的Class
- Java运行时动态加载类之ClassLoader加载class及其依赖jar包
- Java ClassLoader加载.jar
- Java ClassLoader加载.jar
- Java ClassLoader加载.jar
- Java基础加强---ClassLoader(类加载器)
- java中的ClassLoader类加载器
- Java中的类加载器(ClassLoader)及类的加载机制
- 【java】自定义ClassLoader 加载外部类和jar文件
- 实现java classloader 动态加载jar包
- Java类加载/ClassLoader
- 用GPUImage做自己的滤镜
- Objective-C 属性特性(assign , retain , copy , readonly , readwrite , atomic , nonatomic)专业App,微信,网站开发 麻城
- oracle-存储函数
- servlet与jsp的生命周期
- Apache Thrift - 可伸缩的跨语言服务开发框架
- Java ClassLoader基础及加载不同依赖 Jar 中的公共类
- windows下编译Matconvnet的方法(CPU和GPU)
- PHP判断数组内容是否都为一样的值
- pat 1005 - 1008
- xindeDao
- 子串分离
- postfix 部署
- android APP集成支付宝支付
- java发送post请求代码