浏览 5367 次
锁定老帖子 主题:Java的动态加载机制分析和应用
精华帖 (0) :: 良好帖 (0) :: 新手帖 (4) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2009-05-27
最后修改:2009-05-27
要弄清楚动态加载(热部署),首先要明白以下几点: (1)一个classLoader实例只能对一个类加载一次。 (2)通过defineClass方法,可以动态加载类文件的byte数组到classloader实例中 (3)ClassLoader的loadClass方法加载类的顺序是:先用bootstrap classLoader加载类,如果加载不到,则用extClassLoader加载类,最后用system classLoader加载类 (4)假设某个自定义的CustomClassLoader用defineClass加载类,并且CustomClassLoader并没有覆盖loadClass方法。CustomClassLoader加载一个实现了接口IA的类A,那么defineClass会调用父类的loadClass,加载接口IA到system ClassLoader中。然而A被加载到了CustomClassLoader的实例中。 基于以上前提,若想达到对类A的热部署,不需要覆盖loadClass方法,让system ClassLoader加载接口,所以在由system classLoader加载的类中(也就是面向开发人员的代码中)可以通过类型转换IA a=(IA)clazz.newInstance(); 来访问动态加载的A的实例。但是因为每个classLoader实例只能对类加载一次,所以每次动态加载的时候,都需要创建一个classLoader实例来加载实现。 在实际应用中还要考虑动态加载点,也就是说什么时候对那些需要热部署的类进行动态加载。在网络应用中,如果要对某个长链接进行自定义处理,那么可以在链接建立的时候动态加载类。对于短链接的话,可以通过JMX手动动态更新类。也可以通过某个定时器来动态加载。 用动态加载的观点来看远程过程调用,就是说本地保存远程的接口,该接口是由本地的system classloader加载进来的,实现类通过byte流传过来,然后用特定的classLoader实例来加载该实现类。因此实现了远程过程调用。 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2009-05-27
可能是我理解的问题
远程调用不需要客户端自定义classloader,比如 Client A 存放一个类的存根,Server B存放实现 那么数据流动是这样的 A ------(请求调用某个实现类,封装好的参数类名信息等)------> B B -------(实现类被调用后返回的结果)-----------------> A 需要自定义classloader的只是 Server B服务器,启动时加载一次所有实现类的jar |
|
返回顶楼 | |
发表时间:2009-05-27
classloader没有研究过
不过有没有可能把某个server端的class文件 传到客户端 并运行某个方法 (属性也有存在的必要) 像动态变化接口的实现一样. |
|
返回顶楼 | |
发表时间:2009-05-28
抛出异常的爱 写道 classloader没有研究过
不过有没有可能把某个server端的class文件 传到客户端 并运行某个方法 (属性也有存在的必要) 像动态变化接口的实现一样. 这个不太可能,因为可能这个类又引用了很多客户端没有的类,并且这个类还有本地方法。 |
|
返回顶楼 | |
发表时间:2009-05-30
bachmozart 写道 可能是我理解的问题
远程调用不需要客户端自定义classloader,比如 Client A 存放一个类的存根,Server B存放实现 那么数据流动是这样的 A ------(请求调用某个实现类,封装好的参数类名信息等)------> B B -------(实现类被调用后返回的结果)-----------------> A 需要自定义classloader的只是 Server B服务器,启动时加载一次所有实现类的jar 感觉不是B将结果返回给A,而是B将class bytes返回给A,然后由A的classLoader来加在class bytes所对应的类。这个class loader可以自定义,也可以是system classloader,就看需求是什么样子的。 |
|
返回顶楼 | |
发表时间:2009-05-30
java.lang.Object 写道 抛出异常的爱 写道 classloader没有研究过
不过有没有可能把某个server端的class文件 传到客户端 并运行某个方法 (属性也有存在的必要) 像动态变化接口的实现一样. 这个不太可能,因为可能这个类又引用了很多客户端没有的类,并且这个类还有本地方法。 如果客户端引用的类在客户端已经被加载或者存在这些类,那么就可以。而且加载所依赖类的时候,未初始化时,初始化时,运行时都有可能加载。所以如果被依赖的类在某个不可见的方法内,那么应该也是可以的。 但是有一点是,服务器端传过来的class bytes,如果对应的类是一些jdk里边的类,如java.lang.String,客户端加载时需要小心,应该是首先用本地的class loader(例如bootstrap classloader)加载。因为如果采用自定义的加载,可能会产生一些安全问题。例如服务器端有些破坏性的实现。如果被委派到bootstrap classloader加载,bootstrap classloader会检查已加载的类,发现如果加载了,就不用加载String了。 |
|
返回顶楼 | |