双亲委派模型并非强制约束,以下几类典型场景需要打破它:
第一,SPI 机制(Service Provider Interface)。典型如 JDBC:Driver 接口定义在 JDK 核心库(由 Bootstrap 加载),但实现类(如 MySQL Driver)在应用 classpath 下。按双亲委派,Bootstrap 无法委派"向下"加载实现类。JDK 的解法是线程上下文类加载器(ThreadContextClassLoader),让核心代码通过 TCCL 反向加载应用类路径中的实现——这本质是对委派的"作弊"。JNDI、JAXB 等 SPI 同理。
第二,热部署与模块化容器。Tomcat 为隔离各 Web 应用,让每个应用用自己的 WebappClassLoader 优先加载本应用的类(先自己后父,与双亲委派相反),实现应用间同名类隔离与热替换。OSGi 则把类加载做成网状委派模型,按依赖关系精确查找。
第三,热替换/代码动态更新场景(如 JRebel、Arthas 类增强),需要用一个新 ClassLoader 加载同名类的新版本——同名类要共存,必须由不同加载器加载。
打破方式:继承 ClassLoader 重写 loadClass 改变委派顺序(只重写 findClass 则仍遵守委派)。
追问方向:为什么 Tomcat 仍对 JDK 核心类遵守委派?
(约 370 字)