「java双亲模式」java双亲委派模型
本篇文章给大家谈谈java双亲模式,以及java双亲委派模型对应的知识点,希望对各位有所帮助,不要忘了收藏本站喔。
本文目录一览:
- 1、Classloader、插件化开发(结合Presto)
- 2、深入java虚拟机中类装载器解释中 为什么是双亲委派模式 而不叫单亲委派模式呢?类装载器中提到
- 3、java双亲委托机制是什么意思?
- 4、java类加载为什么采用双亲委派模型
Classloader、插件化开发(结合Presto)
注意:
双亲委派模式是在Java 1.2后引入的,其工作原理的是:
双亲委派模式优势
一般来说,例如程序 hello.jar 执行到:
会按照双亲委派模型进行加载类 Demo 。如果 Demo 在 hello.jar 内, AppClassLoader 就将其加载完成;但是如果例如 SPI 这种,既不在应用 hello.jar 内又不在系统类路径内,那么就要抛弃双亲委派模型,获取 线程上下文类加载器 加载( 线程上下文类加载器 默认是 AppClassLoader ,此时的 线程上下文类加载器 肯定是自定义的类加载器)。
自定义一个 破坏双亲委派模型的类加载器 的方法:
深入理解Java类加载器
这里介绍2种加载方式:
例如要加载类:
将其编译为class文件,存放在路径 /Users/root/Projects/idea/my/com 。
这时要加载它:
对于SPI这种,就需要用到ServiceLoader加载。可以参考地址:
需要注意:
知识点
插件化的一个重要目标就是利用类加载器实现类隔离(比如不同厂商版本的依赖包),其原理在于在类中(例如 Demo )隐式类加载器就是 Demo 的类加载器(一般为插件类加载器),对于插件中出现的插件外的类(例如SPI接口类)则不加载。
这里分析Presto的connector插件架构。
Presto的自定义类加载器 PluginClassLoader 继承 URLClassLoader 类并重写了 loadClass ,其类加载逻辑为:
注意:
Java 自定义 ClassLoader 实现隔离运行不同版本jar包的方式
从上面我们得知,如果采取ServiceLoader的SPI方案,应该在 resources/META-INF/services 中存放实现类的全限定名。有意思的是Presto的插件基本都没有这个声明文件,但是编译打包后插件模块的 target/classes 中却能找到。如果观察插件的 pom.xml 文件,就会发现 packagingpresto-plugin/packaging 。其实在根 pom.xml 中使用了presto自己的打包插件 presto-maven-plugin ,将该maven插件打开看就能发现 ServiceDescriptorGenerator 中会在打包时自动生成了声明文件。
SOFA-Ark 是蚂蚁金服开源的一款基于Java实现的轻量级类隔离加载容器。
具体可以参考博客: sofa-ark类隔离技术分析调研
站在插件的角度看待,我觉得:
你应该知道的Java Classloader - 知乎
深入java虚拟机中类装载器解释中 为什么是双亲委派模式 而不叫单亲委派模式呢?类装载器中提到
深入java虚拟机中类装载器解释中 为什么是双亲委派模式 而不叫单亲委派模式呢?
这就是名称问题而已,不管是继承自一个类还是实现多个接口,本质都要用到invoke指令,
双亲单亲仅仅是个名称而已。
方法区中存储着的 类 型信息。命名空间 这命名空间在这里指的是所有 类 的命名空间,不同于类实例的命名空间,开发人员也没有办法去强行指定类实例放在哪个命名空间中。不需要关心,因为不需要关心具体的内存资源释放,透明的。只所以叫方法区我想不仅仅是因为存储了类型信息,而是为索引或者其它必要的操作提供了很多方法,而这些方法对开发人员来说几乎接触不到罢了。方法区更像是一个提供了管理类等操作的容器。
java双亲委托机制是什么意思?
这个机制是 java class loader 范畴的内容。‘
java 虚拟机要将被用到的java类文件通过classLoader 加载到JVM内存中。
首先classloader 分三个级别,最上级 : bootstrap classLoader 中间级:extension classLoader 最低级 app classLoader.
当需要加载某个类的时候,会看看这个类是否已经被加载了,如果没有,会请求app 级来加载,app 请求 extension 级 extension 请求 bootstrap级, 由最高级来负责加载(这个就是双亲委派,委托 上两级的loader来做加载),如果高级的无法加载 则会将人物返回给 下一级 以此类推 最后如果双亲都不行 就由自己来加载。 为什么要用这个机制? 比如 java.lang.String 这个类,这个是jdk提供的类, 如果我们自定义个 包名:java.lang 然后在里面创建一个String 类, 当我在用String类的时候,根据前面所说,是由bootstrap级的loader 来进行加载的,这个时候它发现其实已经加载过了jdk的String了,那么就不会去加载自定义的String了,防止了重复加载 也加大了安全性。
纯手打,有问题指正。
java类加载为什么采用双亲委派模型
采用双亲委派模型使得java类随着它的类加载器一起具备了一种带有优先级的层次关系。
例如类java.lang.Object,它存放在rt.jar中,无论哪个类加载器要加载这个类,最终都会委派给启动类加载器进行加载,因此Object类在程序的各种类加载器环境中都是同一个类。相反,如果用户自己写了一个名为java.lang.Object的类,并放在程序的Classpath中,那系统中将会出现多个不同的Object类,java类型体系中最基础的行为也无法保证,应用程序也会变得一片混乱。
java双亲模式的介绍就聊到这里吧,感谢你花时间阅读本站内容,更多关于java双亲委派模型、java双亲模式的信息别忘了在本站进行查找喔。