Java(5)-双亲委派机制

如何理解双亲委派机制

双亲委派机制是Java中类加载器加载类的一种方法,可以想象一个大家庭中的孩子想要一本书来阅读:
在这个家庭中,孩子会先向他的父亲(子类加载器)要这本书,如果没有这本书,他的父亲就会去向孩子的祖父(父类加载器)要这本书。这个过程会一直持续,直到到达家族中的最高辈分,通常是引导类加载器(Bootstrap ClassLoader)
如果在这一连串的查询中,任何一个家长找到了这本书,他就会将书传给请求的孩子。这样做的好处是,确保了所有人都在使用同一版本的书籍,避免了可能出现的混乱或不一致。
如果整个家族中没有人有这本书,那么最初被问到的父亲(子类加载器)可能会决定去书店(文件系统或其他来源)买一本。一旦买到书,他会按照同样的路径,把书传递回去给孩子。
这种机制确保了Java环境中类的加载是有序的,可以避免类的重复加载,并且有助于保持安全和整洁的代码环境。它也帮助系统维护者更好地控制类的版本和提供统一的行为
我们再用比较书面的表达重新理解双亲委派机制的流程:
1. 缓存查找:当一个类加载请求发生时,类加载器首先检查其内部缓存,看是否已经加载过请求的类。如果找到了,就直接返回该类,不再进行任何加载。
2. 双亲委派:如果在自己的缓存中没有找到该类,类加载器会遵循双亲委派模型,请求其父类加载器进行加载。这个过程会一直向上递归,直至最顶层的类加载器(通常是引导类加载器)。[类加载序列:自定义类加载器 -> 应用程序类加载器 -> 扩展类加载器 -> 启动类加载器]
3. 自行加载:如果所有的父类加载器都不能加载该类(即它们的缓存中也没有这个类,并且它们尝试从自己的资源中加载失败),控制权最终会回到发起请求的类加载器。这时,如果该类加载器有权从文件系统或其他资源中加载类,它将尝试自行加载这个类。
4. 缓存结果:无论类是由哪个类加载器加载的,一旦加载成功,该类的定义会被存储在相应加载器的缓存中,以便未来可以快速访问。

双亲委派机制用了什么设计模式

GPT告诉我的,可能有误。
双亲委派机制在Java的类加载器中使用了代理模式(Proxy Pattern)。这种模式涉及到使用一个代理对象来控制对另一个对象的访问。在双亲委派模型中,每个类加载器(子类加载器)在尝试加载类时,首先会代理请求给其父类加载器,这种代理继续向上直至达到最顶层的类加载器,通常是引导类加载器。
这种设计允许系统保持类加载的顺序和层次,同时确保每个类只被加载一次,防止重复加载同一个类。通过这种代理方式,Java的类加载机制能够提供一个更加安全和可控的环境,因为最上层的类加载器控制了所有下层加载器的加载行为,保证了系统类的优先加载和应用类的隔离。这样不仅有利于安全性,也有助于避免类的版本冲突。

为什么要用双亲委派模型

  1. 避免类的重复加载: 通过委派给⽗类加载器加载类,可以确保同⼀个类不会被多个类加载器重复加载。这有助于节省内存资源,并确保类之间的互操作性。
  2. 保护Java核心类库:由于双亲委派机制的存在,用户自定义的类加载器无法直接加载java核心类库,有助于保护核心类库的安全性,防止恶意代码篡改或者破坏。
  3. 维护类加载器的层次结构:双亲委派模式使得各级类加载器可以按照⼀定的层次结构来组织和管理。这有助于降低类加载器的复杂性,简化类加载过程。

双亲委派机制的缺点

  1. 类版本冲突:当不同的库或框架需要不同版本的同一个类时,双亲委派模型可能会导致问题。由于类加载器首先会尝试从父加载器那里加载类,因此可能最终使用的是一个不符合当前需要的版本。这在大型应用或多模块应用中尤其成问题,可能需要精细地管理类路径和加载器的结构。
  2. 加载器行为的僵化:双亲委派模型在设计上是僵化的,因为它强制要求所有的加载请求必须遵循固定的父到子的顺序。这限制了更灵活的加载策略,比如动态加载或热替换类,这些策略在某些应用开发中可能非常有用。
  3. 调试和故障排查难度增加:当类加载问题发生时,由于类加载过程涉及多个加载器和可能的递归委派,这使得调试和故障排查变得更加复杂。开发者需要清晰地理解各个加载器的层级和作用,才能有效地定位和解决问题。
  4. 灵活性降低:在某些情况下,开发者可能需要绕过标准的类加载机制来满足特定的需求,如在运行时动态地替换或修改类的行为。由于双亲委派模型的严格性,这些需求可能难以实现,或者需要采用更复杂的解决方案。
  5. 影响插件化架构:在插件化的应用框架中,双亲委派模型可能会阻碍插件之间的类隔离。例如,如果两个插件依赖于不同版本的同一个库,标准的双亲委派模型可能不足以解决这种隔离需求,需要额外的技术手段来处理。

如何打破双亲委派模型

类的加载方式默认都是双亲委派。
如果我们有一个类想通过自定义的类加载器来加载,而不是通过系统默认的类加载器,就需要打破双亲委派机制。
双亲委派的机制是ClassLoader中的loadClass方法实现的,打破双亲委派,其实就是重写这个方法,来用我们自己的方式来实现即可。
面试必备:什么时候要打破双亲委派机制?什么是双亲委派? (图解+秒懂+史上最全) - 疯狂创客圈 - 博客园

posted @ 2024-05-04 13:39  marigo  阅读(24)  评论(0编辑  收藏  举报