双亲委派模型

双亲委派模型的工作机制:如果一个 ClassLoader 收到了加载类的请求,它会首先将这个请求递归委派给 parent ClassLoader,并且最终请求会委派给 BootStrap ClassLoader,只有当 parent ClassLoader 无法加载这个类的时候,children ClassLoader 才会尝试自己去加载。

  1. +---------------------+
  2. |BootStrap ClassLoader|
  3. +---------------------+
  4. ^
  5. |
  6. +--------------------+
  7. |Platform ClassLoader|
  8. +--------------------+
  9. ^
  10. |
  11. +-----------------------+
  12. |Application ClassLoader|
  13. +-----------------------+
  14. / \
  15. / \
  16. +----------------+ +----------------+
  17. |User ClassLoader| |User ClassLoader|
  18. +----------------+ +----------------+

使用双亲委派模型的好处是使被 ClassLoader 加载类具有了一种优先级的层次关系,例如 java.util.Object 类只需被 Bootstrap ClassLoader 加载一遍即可,同时在程序中获取的所有 Object 类都会是同一个类。

破坏双亲委派模型

双亲委派模型本身也存在一些缺陷:例如,当在基础类库中需要调用业务层代码的时候,使用加载基础类库的类加载器(例如 BootStrap ClassLoader)便会无法加载到业务层的类。为了解决这个问题, Java 设计团队引入了线程上下文加载器(Thread Context ClassLoader),可以通过 java.lang.ThreadsetContextClassLoader() 设置线程的上下文类加载器。

在追求程序的动态性时,双亲委派模型也会成为阻碍。在实现「代码热替换」、「模块热部署」等功能的时候,需要在平级的类加载器中查找和加载类,在这一点上便是破坏了双亲委派模型的原则。