SPI如何破坏双亲委派模型
类加载器(classloader)
先从类加载器说起,凡事先问是什么,首先什么是类加载器?
我们知道,一个 *.java 的代码源文件要执行起来之前,必须通过 javac 构建抽象语法树并编译成字节码,字节码仍然是不能被机器所识别,那么一个 .class 文件要被机器识别并执行的前提就是将字节码转化成机器码加载到内存里,这一转化过程就是类加载的执行过程。
当然,这整个过程细节并非这个问题的讨论重点。
类加载器便是在在这个过程里的加载阶段起作用,负责将 .class 文件字节码提取出来,转化成二进制字节流。
(但是这离成为真正的类还有十万八千里。。。)
一个Java应用中通常存在三个类加载器(Classloader):
- Bootstrap Classloader 启动类加载器:负责加载/lib 下的核心类库,此加载器本身内嵌于JVM,在 Java 中找不到具体的引用;
- Extension Classloader 扩展类加载器:负责加载/lib/ext 下的扩展类库;
- Application Classloader 系统应用类加载器:负责-classpath 指定路径类库加载。
他们三者并非典型的继承关系,而是子指派父为自己的 parent。
(这里有个源码细节,由于启动类加载器是
内嵌于 JVM 且无法被引用,因此 Extension Classloader 指派 parent 为 null,即等同于指派启动类加载器为自己的父加载器)
为了有足够灵活性,类加载器也是允许自定义的。这不禁思考,这么多类加载器之间是怎么协调类加载任务的?
这就引出了本文的重点,双亲委派模型。
双亲委派(parents deletation model)
双亲委派模型是什么?
The Java platform uses a delegation model for loading classes. The basic idea is that every class loader has a "parent" class loader. When loading a class, a class loader first "delegates" the search for the class to its parent class loader before attempting to find the class itself.
由于翻译问题,这里双亲的 “双” 并没