jvm 双亲委派模式
Posted Java技术联盟
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了jvm 双亲委派模式相关的知识,希望对你有一定的参考价值。
覆盖第三方包的代码,这里用到了一个不常见的Java知识,双亲委派机制。利用双亲委派机制,可以很巧妙的重写第三方包的部分逻辑,不必维护第三方包的代码。为了更好的理解双亲委派机制,需要先了解类加载与类加载器相关知识。
什么是类加载机制?
Java虚拟机把编译后的Class文件加载进内存,并对数据进行校验,转换解析和初始化,最终形成可以被虚拟机直接使用的Java类型,这就是虚拟机的类加载机制。对于任意一个类,都需要由加载他的类加载器和这个类本身一同确立其在Java虚拟机中的唯一性。
Java的类加载器有四种
Bootstrap ClassLoader:根类加载器,负责加载Java的核心类,它不是java.lang.ClassLoader的子类,而是由JVM自身实现
Extension ClassLoader:扩展类加载器,扩展类加载器的加载路径是JDK目录下 jre/lib/ext,通过扩展类加载器的getParent() 方法返回的是null,实际上扩展类加载器的父类是根加载器
System ClassLoader:系统(应用)类加载器,它负责在JVM启动时加载来自java 命令的 -classpath选项,或者通过CLASSPATH环境变量所指定的jar包和类路径。
User ClassLoader:自定义类加载器,加载用户创建的自定义类
什么是双亲委派机制?
双亲委派机制作用
避免类的重复加载。当父类加载器加载了该类时,子类加载器就不会再加载一次。
防止java核心API被随意替换。
如何破坏双亲委派模型?
第一次破坏:向前兼容,类加载器和抽象类java.lang.ClassLoader则是JDK1.0时候就已经存在,JDK1.2之后的java.lang.ClassLoader添加了一个新的proceted方法findClass(),自定义的类加载逻辑写到findClass()方法中。在loadClass()方法的逻辑里,如果父类加载器加载失败,则会调用自己的findClass()方法来完成加载,这样就可以保证新写出来的类加载器是符合双亲委派模型的。
第二次破坏:加载SPI接口实现类,一个典型的例子便是jdbc服务,它的代码由启动类加载器去加载,但jdbc的目的就是对接口进行统一的管理,它需要调用独立厂商实现部署在应用程序classpath下的JDBC接口提供者的代码。但启动类加载器不可能“认识”这些代码,为了解决这个问题,便引入了线程上下文件类加载器(Thread Context ClassLoader)。这个类加载器可以通过java.lang.Thread类的setContextClassLoader()方法进行设置,如果创建线程时还未设置,它将会从父线程中继承一个;如果在应用程序的全局范围内都没有设置过,那么这个类加载器默认就是应用程序类加载器。有了线程上下文类加载器,jdbc服务使用这个线程上下文类加载器去加载所需要的jdbc实现类的代码。
第三次破坏:热部署,为了实现热插拔,热部署,模块化,意思是添加一个功能或减去一个功能不用重启,只需要把这模块连同类加载器一起换掉就实现了代码的热替换。
以上是关于jvm 双亲委派模式的主要内容,如果未能解决你的问题,请参考以下文章