00:00
那接着呀,咱们来看下一个问题,叫关于自定义类的加载器,那前面的话呢,我们提到过整个关于Java层面这个类的加载器呢,我们有这样的一个层次关系,对吧?这个呢,是从我们所谓的叫这个呃类加载器和它的这个负类,当然这个副类呢,我们说得加个引号对吧?这个层面呢,我们去看的说呢,呃用户自定义类的加载器,它的默认的负类加载器呢,属于叫呃应用类这个加载器,或者叫系统类加载器,这个是一个层面,那从另外一个层面来看的话呢,就是我们呃这些类的加载器都是Java这个。语言层面的他们呢,都是继承了,哎,继承于这个class loader对吧?好,那我们来看一下这个自定义类加载器的这个相关情况。前面的话呢,我们其实有几处这个代码呢,这个已经拿着,呃,我这块写好的自定义类的加载器呢,带着大家呢,去测验测试过相关的一些这个操作啊,那这块呢,我们具体来说一下。首先的话呢,我们先明确一个问题,就是说为什么我们要去自定义类的加载器啊,这儿呢,也包括我们在很多呢这个场景下呢,也都见到过自定义类的加载器,对吧?那为什么出于什么样目的我们要自定义呢?那这呢,我们提供了叫四条原因,首先第一个呢,叫隔离加载类。
01:10
那这呢,也是我们非常突出的一个应用场景说呢,在某些某些这个框架内进行这个中间件与应用的一个模块隔离,那为了我们把这个类啊加载到不同的这个环境当中。那比如说像阿里的某容器当中,容器框架里边,呃,就使用自定义类的加载器呢,把应用当中依赖的炸包和我们这个中间键呢,依赖这个炸包呢,给它做了一个分离。啊,做了一个分离,那因为我们知道了,像这个中间件呢,它都有自己依赖的这个炸包,对吧,那当你在同一个工程的多个这个呃框架里边,呃,你要是去使用的话呢,是不是往往会被迫我们要进行一个叫类的仲裁。啊,那也就意味着我们按照某种规则的话呢,这个炸包必须呢,要统一为一个版本。啊,那这呢,就导致我们这个类啊,如果你存在呢,这个包路径啊,或者是类名啊,都相同的情况下呢,就出现一个叫类冲突的问题。
02:04
对吧,类冲突的这个问题啊,这呢,我们把这刚才说的这个词呢,写一下啊,第一个呢,就实现呢,叫类的一个仲裁。啊对吧,那类的仲裁呢,呃,就会导致呢,我们发现呢,就是同一个全类名的这个类呢,它就会出现一个冲突的问题。啊类冲突,那你要出现这个冲突的话呢,我们这时候呢,就必须要决定啊,你应该用具体的哪一套这个相应的这个炸包的一个数据了。对吧,那就得出现这样的一个问题啊,那或者说你要不去做这个这个解决的话呢,那就会出现相关的一些异常,那么主流的像这个容器类的这个框架的话呢,一般都有自己的这个自定义类的加载器啊,实际上呢,就是不同的这个中间键呢,相互之间这个类是隔离的啊,避免这个类的一个冲突问题啊。那另外呢,再比如像咱们这个tomcad啊,属于这个web服务器了,那web服务器里边呢,它也定义了好几种这个类的加载器,那隔离呢,同一个web应用服务器上呢,不同的应用程序。
03:01
那这呢,就需要使用咱们叫自定义类的加载器。第二呢,就是说呃,修改类的加载的方式啊,类的加载模型呢,并非强制说除了这个BOO之外呢,其他这个类的加载呢,并不是说一定要引入的,那我们可以根据实际情况呢,按需进行加载啊,动态加载是吧,就修改加载的方式。那再者呢,就是扩展加载源,那我们可以从像数据库啊,网络呀,包括像电视机机顶盒啊等等这个方向,我们去加载相关的这个二进制的数据啊,就是扩展加载源,另外一个提到就是防止源码的一个泄露啊,这个呢也是我们说非常重要的一个事情。咱们知道呢,这个Java代码呢,咱们编译之后呢,生成这个自解码文件,咱们也带着大那分析过这个自解码文件对吧?那这个自解码文件呢,其实按照这个规则也很容易的,是不是被反编译啊,那我们如果希望呢,呃,这个数据呢,这个进行一个保护,那我们可以呢,针对这个编译行为呢,进行一个加密。那得到的这个四解码文件的话呢,是加密以后的,那么要想我们把它呢,这个加载并且初始化,并且去执行,那我们需要呢,自定义类的加载器啊,按照你指定的规则呢,去解密才行对吧?那这个时候呢,我们就可以正常的去执行我们的程序啊,但同时呢,自建码文件呢,还是一个加密的状态。
04:16
啊,就是防止这个源码泄露对吧?好,那基于这样的好处呢,我们就有具体的常见的场景,那常见场景里边呢,呃,其实这个呢,是我们见的比较多的是吧,在不同的这个容器空间当中,我们这个对应用呢,进行隔离啊,这呢主要也体现的是我们第一个点啊,第二个呢,主要体现的呃,也提到了我们这个防止源码泄露的问题,包括呢,扩展数据源的一个问题,OK。啊行,那这里边有一个注意点,大家需要看一下,就是我们前面提到了说不同的类的加载器,咱们如果加载一个呃,某一个包下的某,呃这个具体的一个类的时候啊,那这个自解码文件呢,可能是同一个,但是呢,如果咱们使用的是不同的类的加载器。这是一个,然后还有一个呢,加载器二,那加载以后呢,我们是不是会生成内存中的两个,这个运行过程当中这个类模板数据是吧?那这两个的话,你注意它是两个不同的这个类型,那如果呢,你发生了说这个类的一个子类对象呢,呃,这个项付给他,但是你可能又付给他了啊,这时候呢,一不小心付给他了,这时候你要注意代码层面呢,可能说这个这个这个指定的类型是没问题的,但实际上呢,它会出现异常。
05:24
对吧,会出现异常,因为呢,我们不看做是同一个类型。啊,这就涉及到我们讲的那个命名空间的问题,那这一点呢,是需要大家小心啊来进行处理的,好,那这呢是我们对这个自定义类加载器的一个好处呢,呃,以及这个应用场景呢,做了一个说明,那下面呢,我们就来看一下如何去实现。
我来说两句