背景
前面解决阻塞问题时,看到了DriverManager.getConnection,里面init时用到了Thread ContextClassLoader加载默认驱动,比较好奇。
省流
各类SPI机制都可能用到Thread ContextClassLoader
因为
- SPI核心类在BootClassPath下,加载它的是BootstrapClassLoader
- BootstrapClassLoader是万物之源,没有双亲,由C编写加载最核心的JVM必要jar。它只加载自己的boot路径的class类
- SPI却需要反向去加载猴子猴孙们的SPI实现类,倒反天罡
于是
- 有了线程上下文类加载器,做个中介,和ThreadLocal本质差不多。
还有没有其他办法?
- 有
1如果SPI实现的jar类范围可控,比如只是一个驱动jar,那可以-Xbootclasspath:/a/b/c/jar 添加一个。就是不太优雅显式要求指定路径,但更明确可控。
2如果你们有人比较懂JVMTI,这是C的东西底层JVM开的口子,可以调用C方法来添加bootclasspath,性价比低属于【1】的炫技。
3SPI可以构建某种工厂,把SPI实现类的加载和实例化外包出去,提供注册服务。