利用ClassLoader实现动态热布署

转载 2011年01月11日 18:33:00

          大型应用中,系统是不能轻易停机的,一般选择升级都是选在晚上人少的时候进行停机维护。这样大大的降低了系统的可用性,也提高了系统维护的成本。因此如果能够实现在不停机的情况下能够进行系统的维护或者升级,则能够很好的解决上面的情况。在JAVA中我们可以利用CustomerClassLoader来实现以上机制。

在开始之前先简介一下JAVA中的ClassLoader机制。Java中类的实例化分为两部分:类的加载与类的实例化。而类的加载一般分为两种情况,显式加载和隐式加载。显示加载就是我们使用Class.forName而隐式加载的话就是我们平常使用最多的new.new关键字会在后台为我们做一些工作。

JAVA的类加载机制是分为几个层次来加载的。首先我们来看一下JAVA的加载器的层次结构:

 

ClassLoad Struct

 

 

1,BootStrapClassLoader是根加载器,它默认加载的是jre/lib目录下面的jar.或者是你在jdk的启动参数里面指定的:-XbootClasspath

2,ExtClassLoader加载器,它默认加载的是jre/lib/ext目录下面的jar,或者是启动参数里-Djava.ext.dirs 指定的目录

3,AppClassLoader加载器,它默认加载的是classpath变量指定的目录,其实就是我们应用程序的class目录。

4,CustomeClassLoader加载器,这是我们自已定义的加载器,必须要继承ClassLoader类。可以根据用户的需要定制自己的类加载过程,在运行期进行指定类的动态实时加载

而JDK的加载过程分为两个过程,第一步是:从下到上检查加载器的命名空间内(每个class在命名空间内只存在有一份)是否已有要加载的Class.如果找到则直接返回其引用,如果没有。则从上到下从各自的目录下去加载指定的class.如果到了最底层还没有加载成功。则抛出noclassfound的异常。其加载流程,详见如下图:

 

 

 

 

接下来,我们初步的了解了JDK的ClassLoader加载机制后,可见我们要实现动态的热布署,我们可以用CustomerClassLoader来实现我们的功能。自定义的ClassLoader需求要继承ClassLoader类。下面对于ClassLoader中的几个重要方法做一下介绍。

findLoadedClass:从当前类加载器的命名空间内查找指定的class,如果存在则返回其引用。不存在则返回null

getSystemClassLoader:调用系统使用的加载器,有时候我们自定义的类加载器可以调用它来执行一些其它的事情

resolveClass:链接一个指定的类,在某些情况下保证这个类一定可以用

defineClass:从class字节文件生成一个class对象

loadClass:加载类的入口方法,显式的加载类的方法。

下面我们看一下实现的自定义的类加载器:

 

 

 

 

在以上代码段中,我们在构造方法中,调用了super(null),这样的做法就是让我们定制的加载器的父加载器为null.这样避免我们定义的类被父加载器(AppClassLoader)抢先加载。在loadClass中我们首先从自已的类加载器的命名空间内查找要加载的类。如果没有找到。则让系统的加载器加载。

 

 

 

调用的类:

 

 

 

在以上类中,我们让系统每隔三秒种调用一次run程序。然后运行我们系统,可以看到控制台打出如下语句:
hello version 1
hello version 1

热下来我们不要停我们的应用,直接修改Foo的代码如下:

可见修改后打出如下语句:

hello version 1
hello version 1
hello version 1
hello version 2
hello version 2

代表已经替换成功了。

注意:有朋友会说为什么不把上面的反射的代码改成

 

 

 

 

这样呢,这样更明了,但是这种情况下。系统会报错:ClassCastException,因为你强转的时候的Foo是由AppClassLoader加载的,而我们的foo是由自定义的加载器加载的。在JDK中,继使两个类的类型相同,但是由不同的加载器加载的话。虚拟机也会认为这是不同的类型。但是我们可以通过接口来实现。是不会报错的,可以改成如下代码,则可以运行通过:

 

以上代码中Ifoo是Foo接口。
当然,要实现一个在线自动升级热布署的系统光靠上面这一点代码是不够的,还需要有完善的回退机制,检查机制等。但是以上部分做为core部分,基于以上部分是完全可以打造一个不停机升级的热布署应用。解决大型应用中的维护和升级的问题。

 

 

相关文章推荐

Android Dalvik虚拟机初识

Java的未来由google引导
  • andyxm
  • andyxm
  • 2011-01-10 14:38
  • 50095

JRebel安装使用说明(真正的实现热布署)

开发环境下,tomcat对热布署的支持还是比较弱,致使开发过程中浪费大量时间在重起服务上。发现了Jrebel,它对热布署的支持相对比较全面。 虽然Jrebel官方号称使用它不存在内存泄漏问题,但...

java代码实现利用 classloader 动态加载 jar包、文件夹到classpath中

转载自BlogJava。http://www.blogjava.net/jnbzwm/archive/2011/04/01/347491.html 在项目中实现了一个工具(独立运行的Ja...

利用Cobbler批量布署CentOS

从事网游运维的兄弟们应该深有感触,往往在开新服的时候需要大批量的布署新的服务器,时间紧迫而且量大,装系统、初始化,枯燥而又乏味,有时还容易出错, 为了解放我们的双手,所以要实现自动化,Red Hat ...

搭建git服务器及利用git hook自动布署代码

我喜欢 github,我现在的个人代码全部是托管在上面了,但是一些公司或者某些项目不适合放入github中,你希望能有一个完全私有的仓库,如果你有一台服务器,这显然是很容易办到的事。 下面简单的...

利用classloader动态加载jar包

利用classloader动态加载jar包

利用自定义ClassLoader和接口逻辑后台可刷新缓存实现java-web项目的动态发布

1。设计思路 通过后台管理界面上传jar包实现动态发布

Servlet—tomcat布署:web.xml 亲——你中招了没有?

两天前开始在tomcat上布署Servlet程序,参照《servlet和jsp学习指南》和网上一些博客 只有一个小小的原因竟然让我耽误了两天时间,因为看的书和网上所有的布署教程都很旧, 一开始我是直接...

JBoss下布署Spring2.5和Struts2系统

目前在做JBoss下布署String2.5 & Struts2集成的工程,在工程中用Spring2.5 的component scan, Struts2 的convention 和 rest plug...
  • fhx007
  • fhx007
  • 2011-05-31 22:31
  • 2448

VS2005项目的安装与布署,包括卸载

一、VS2005制作安装包的“系统必备”选项“系统必备”,通过该选项,可以选择部署应用程序需要预先安装的组建,包括。net fx和MDAC等。“系统必备”选项中可以不仅可以选择需要预安装的组件,而且提...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)