「SPI」 全称为 (Service Provider Interface) ,是JDK内置的一种服务提供发现机制。 目前有不少框架用它来做服务的扩展发现
双亲委派模型的第二次“被破坏”是ServiceLoader和Thread.setContextClassLoader()
手动设置驱动为com.mysql.jdbc.Driver。DriverManager有一个静态代码块,这会在执行getConnection前运行,即loadInitialDrivers(),此方法会调用ServiceLoader.load(Class service, ClassLoader loader)寻找ClassPath:META-INF/services文件夹下面java.sql.Driver的内容,即实现类,但是jvm并不知道你需要加载哪个实现。
SPI 的接口是 Java 核心库的一部分,是由引导类加载器来加载的;SPI 实现的 Java 类一般是由系统类加载器来加载的。引导类加载器是无法找到 SPI 的实现类的,因为它只加载 Java 的核心库。它也不能代理给系统类加载器,因为它是系统类加载器的祖先类加载器。
load(由于ServiceLoader位于rt.jar包下面(并没有继承ClassLoader)是启动类加载器加载的,所以是无法看见厂商的实现类jdbc.Driver,由父类加载器加载的类是看不见子类加载器加载的类的。所以此时采用自己传入的loader结合Thread.setContextLoader(),将jdbc.Driver偷偷加载到内存,并通过以下详细基本原理,进而实现SPI机制