JVM底层之类加载器子系统加载器和SPI(二)

类加载器

      在JAVA加载器中,有俩种加载器,一种由C++(BootStrap Class loader)写的,另一种由Java写的,由Java写的都继承自 java.lang.ClassLoader


各种类加载器并不存在父子关系,而是通过逻辑代码来进行维护的父子关系,进而实现的双亲委派机制

双亲委派机制


Jvm中 启动类加载器是由C++写的,在Java中并不存在对应的实体类,而是通过Java中的逻辑进行封装调用的。


类加载器加载的类是如何存储的


类存储位置


双亲委派

        如果一个类收到了加载请求,当自身加载器中类不可以交交给逻辑父类加载器进行加载当将加载权交给启动类加载器加载不到类的时候, 此时会一次向下各自的加载器判断是否可以进行加载,当调用到自己怕判断也不能加载时,则会抛java.lang.ClassNotFoundException 异常

好处:避免重复加载 + 避免核心类篡改

双亲委派类加载流程

打破双亲委派的俩种方法

     当需要加载第三方服务商提供的服务时,此时双亲委派机制就不适用了,此时就需要通过Java中线程上下文类加载器ThreadContextClassLoader 来进行加载类,此时加载的路径是从框架指定的固定路径和格式来进行加载的。

   当需要不用系统加载器的时候此时就需要自定义加载器了。

    1.双亲向下委派/SpI 

           主要是通过 ThreadContextClassLoader 来进行保存加载器,以服务可以在使用的时候可以获取到进行使用,Java中加载Driver驱动类的时候,就使用了这种方法,像SpringBoot 、Dubbo、Tomcat也有各自的Spi加载方式。

    2. 自定义类加载器

       需实现 java.lang.ClassLoader 类 ,重写loadClass方法自定义加载逻辑


沙箱安全

跟Linux的权限机制有点像

看openjdk源码会看到有这样的判断AccessController.doPrivileged

随便搜了一下,35个文件有80处安全判断

比如我定义了一个类名为String所在包为java.lang,因为这个类本来是属于jdk的,如果没有沙箱安全机制的话,这个类将会污染到我所有的String,但是由于沙箱安全机制,所以就委托顶层的bootstrap加载器查找这个类,如果没有的话就委托extsion,extsion没有就到aapclassloader,但是由于String就是jdk的源代码,所以在bootstrap那里就加载到了,先找到先使用,所以就使用bootstrap里面的String,后面的一概不能使用,这就保证了不被恶意代码污染


你可能感兴趣的:(JVM底层之类加载器子系统加载器和SPI(二))