00:00
那刚才啊,咱们讲解了历史上的三次破坏双亲委派机制的行为,对吧?那针对于第三类行为呢,我们提到了一个概念,叫做代码的热替换,或者呢,叫模块的热部署,那么针对于这个代码的热替换啊,咱们来进行一步的进行一个解释说明,包括呢,那如何在代码上呢去做一个演示,那我们给大家说一下。首先呢,说这个热替换呢,我们主要指的是在服务的运行过程当中,咱们希望呢,不终止服务的情况下,或者说呢,不终止我们整个这个呃,项目运行的这个情况下呢,我们来修改程序的文件,那修改完文件之后呢,希望呢,这个文件对应的这个代码结构呢,立即表现在我们正在运行的这个系统之上。那希望呢,是这个样子的,我们把这种行为呢,就称为呢叫热替换,这个热呢就可以体现为我们正在运行是吧,这就是一个热啊,就像热身啊,就是身体呢正在活动,对吧?那我们说呢,像这个脚本语言呢,这个天生呢,它就支持热替换的行为,比如说呢,像PHP,那只要呢,我们替换了这个服务器端的PP的这个原文件,那它呢就会立即生效,无需呢我们去重启这个外部服务。
01:13
但是对于咱们障碍语言来讲呢,就不行了,那并非天生的支持这个热替换,那如果一个类呢,已经加载到这个系统当中,通过修改这个类文件啊,并没有办法呢,让系统重新呢,来加载并运行这个类。那因为咱们前面呢,你看也提到过这个文件呢,加载到内存之后呢,之后呢,我们对应一个大的class一个实例啊,那你要是这个替换了class文件,首先的话呢,我们能不能主动的再去加载,这是其中的一个事儿。再一个事儿的话呢,就是即使你能够重新加载,那我们如果呢,使用了不同的类的加载器,那那你这时候呢,显然它也是不同的这个类,对吧,那我们说呢,每个类的加载器都有一个命名空间,不同的类的加载器呢,加载同一个文件,那到内存中呢,其实也是不同的类型,它们是不可以互相转换和兼容的,那怎么办呢。
02:03
那怎么办呢?那这时候我们要想实现热替换呢,呃,就这块儿呢,就给了一种思路,那我们呢,这个呃,每次创建自己的class loader,那需要热替换的这个类,那比如一开始的时候用的是一个,比如我们叫类一对吧,那么我们把它呢,运行起来啊,也跑起来了,那调用它相应的这个,呃,这个热替换这个类的实例的方法啊去执行,然后呢,我们把这个类呢,做一个替换啊当然这个替换呢,其实主要是更新它内部的一些方法,对吧?呃,方法的具体这些实现了啊,我们改成这个一撇了,那这个时候怎么办呢?那我们创建一个新的class呢,诶再重新的去加载一个新的替换的这个类。那然后呢,创建这个类的一个实例,接着呢还去调用它的这个方法,那主要呢,就是实现对这个方法的一个具体的替换了。那这样的一个思路,那这块呢,咱们用这个代码呢,来给大家做一个演示啊,我呢还是定义了一个自定义的类的加载器啊,这咱们后边呢,给大家具体讲这个类的加载器呢,该怎么去实现啊,现在呢,先知道我们定义了一个类的加载器,主要呢,我们去重启了叫find class的这个方法。
03:08
那这呢是一个核心的逻辑,这呢是咱们定义的整个你要加载的对应的自解码文件的那个路径啊,你得告诉我是吧?哎,通过这样方式我们创建一个实例啊,比如说我们具体测试的话呢,就看这,那我这呢创建了一个my class loader,那它呢主要是来加载,那加载呢,就咱们对应的这个src啊,这个路径下的具体的第2CLASS文件,好,那我们想加载的是谁呢?我想加载这个叫DEMO1这样的一个类,这个类里边呢,我定义了一个方法,就叫做hot。里边呢,有一个具体的输出语句行,那首先的话呢,我们这个open terminal在这个位置呢,我先Java c,然后呢叫demo1.java。对我们这个DEMO1的这个类呢,我们进行一个编译,就生成了对应的一个自解码文件,对吧?好,那我们在这个那测试类当中呢,我们就想去加载这个啊,其实就是对应它的这样的一个字节码文件了啊,就是它。
04:02
那我们下边呢,再具具体做的这个事儿,我们把它呢描述一下,首先呢,这一步我们呢,是创建啊自定义类加载器的一个实例,好,那创建完实例之后呢,我们就选择呢,去加载指定的类。哎,加载嗯,指定的这个类,那这个类呢,也是我们自己来定义的,那下面呢,就是创建你这个,哎,我们把这个类呢,称为叫运行室类吧,啊那就是创建运行室类的实例。呃,运行时类的一个实例啊,这个呢都比较简单,我们在反射里边呢,就经常写这样的代码,那由于这个方法的话呢,它是一个非private这个方法,对吧,非private方法我就写成public了,所以呢,我们这直接呢就调get method了,没有调那个get declared啊,那其实一样叫get declare也可以,那因为呢也是个公用方法,所以我们也不用呢,叫set accessible了,那就这呢就比较简单了,直接呢叫哎获取。
05:05
这个运行实内中指定的这个方法。那方法的话呢,通过方法名和行单列表,那由于呢这没有具体的行参了,所以我就省略了后边那个可编行参啊,然后下面呢,就是我们调用指定的方法。行,这个呢,就是我们在实际开发场景当中,我们调的一个具体的方法了,通过反射来实现的,呃,这块呢,我们是使用一个循环,然后每隔五秒钟呢,它去做一个执行,那暂时的话,我们把它跑起来。嗯,抛起来了,抛起来以后呢,大家会发现每隔五秒钟呢,我们就会去执行咱们这个how的方法里边的这个具体的方法体了,叫做O的DEMO1,那每隔五秒钟呢,会输出一次,对吧?那现在的话呢,我们想实现是不是一个热替换呀,那我们现在呢,我就可以做简单的这样的操作,我把这个how的方法里边这方法体啊做一个修改啊,那就相当于改成个new来代一了。
06:02
做了一个修改对吧,那修改完以后呢,那我们呢,这样子做,我不用停下来当前的这个程序,那我们再去啊,对咱们当前的这个类呢,你重新做个编译啊Java c。啊,我们就代1.java。好,这呢,我就做了重新的编译,重新编译完之后呢,大家注意看。啊,这个比较靠后了,你看此时的话呢,我们程序呢,没有停止的情况下,它呢,就开始来加载咱们新生成的这样的一个类。啊,调用它内部的这个方法,那这儿呢,我们就把它看成是一个热代码的一个替换。啊,整个呢,我们刚才的执行过程,其实就满足这样的一个过程。OK,那通过这个呢,给大家做一个简单的一个演示行为,那体现了就是我们双性委派机制呢,这里边儿也是一个破坏行为,那我们这儿呢,调用的是叫什么呀。哎,在这是不是叫find class是吧?哎,直接我们就用find class呢,进行一个类的一个加载,那没有走这个双型派机制啊,直接呢,使用的是我们自定义的这个类的加载器啊来实现的。
07:05
好,这个呢,大家那知道了解一下我们这个行为就可以了,那至此的话呢,咱们把这个双星语派模型呢,咱们就介绍到这儿。
我来说两句