双亲委派模型
为啥叫双亲委派模型而不叫父亲委派模型,明明只有逻辑上的父类委派,没见到“母亲的影子”。而且父类也只是逻辑上的父类,不是典型意义上的通过继承出现的父子类关系,本质上是通过组合实现的代码复用。我们来大致看下。
先熟悉一些概念,绝大多数程序会使用到3这种系统提供的类加载器:
- 启动类加载器,这类加载器负责将放在<JAVA_HOME>/lib目录下的,或者被-XbootClasspath所指定的路径中的,并且能被虚拟机识别的类库加载到内存中,这个类加载器是虚拟机的一部分,其他的类加载器都是由Java语言实现,独立于虚拟机之外的。
- 扩展类加载器,负责将<JAVA_HOME>\lib\ext目录下的,或者被系统变量java.ext.dirs指定路径下的类库加载到内存,程序员可以直接使用扩展类加载器。
- 应用程序类加载器,也称为系统类加载器,负载加载用户类路径classpath上所指定的类库,开发者可以直接使用,也是系统默认的类加载器。
程序由这3中类加载器配和使用进行加载,也可以加入用户自定义类加载器。
双亲委派模型的原理如上图所示,如果一个类加载器收到了类加载请求,首先他不会自己尝试加载,而是把这个请求委派给上层类加载器,每一层都是如此,因此所有的类加载请求最终都会传到最上层的启动类加载器,只有当上层类加载器无法完成类加载请求时 ,子加载器才会尝试自己加载,注意这里的上下层级关系不是通过继承实现的,而是由组合实现的逻辑上的上下级父子关系。
代码热替换 - 模块热部署
双亲委派模型不是强制性的约束模型,而是Java设计者推荐给开发者的类加载模型,实现简单,十Javal类随着它的类加载器一起具备了带有优先级的上下级关系,对保证Java程序稳定运行起到了重要作用 。但是双亲委派模型多次遭到破坏,其中一次破坏是由于用户对程序的动态性追求而导致的。动态性就是指代码热替换,模块热部署。
OSGI的模块热部署就是通过自定义类加载器机制,每一个模块都有自己的类加载机制,当需要更换一个Bundle时,就连Bundle连同类加载器一起替换掉实现模块热部署。